Como obter um valor aleatório do dicionário em python

148

Como posso obter um par aleatório de a dict? Estou criando um jogo em que você precisa adivinhar a capital de um país e preciso que as perguntas apareçam aleatoriamente.

Os dictolhares como{'VENEZUELA':'CARACAS'}

Como posso fazer isso?

tekknolagi
fonte

Respostas:

259

Uma maneira seria:

import random
d = {'VENEZUELA':'CARACAS', 'CANADA':'OTTAWA'}
random.choice(list(d.values()))

EDIT : A pergunta foi alterada alguns anos após a postagem original e agora pede um par, em vez de um único item. A linha final agora deve ser:

country, capital = random.choice(list(d.items()))
Gerrat
fonte
141
Isso funcionará no Python 2.x, onde d.keys()há uma lista, mas não funcionará no Python 3.x, onde d.keys()é um iterador. Você deveria fazer isso random.choice(list(d.keys())).
Duncan
21
@ Duncan: Mal posso esperar até que todas as bibliotecas de terceiros sejam compatíveis com Python 3.x, portanto as perguntas sobre Python não precisam de 2 respostas para cada pergunta.
Gerrat 01/02
9
Err como sobre: d = {'VENEZUELA':'CARACAS', 'CANADA':'OTTAWA'}Hehe, +1 para a lavagem cerebral muito sutil ...
gentimouton
4
@gentimouton ... interessante, mas talvez eu estava apenas indo para a cidade mais populosa em cada país - não os capitais :)
Gerrat
12
Isso é eficiente? Será que essa escala se dict fica realmente grande?
Spectral
26

Eu escrevi isso tentando resolver o mesmo problema:

https://github.com/robtandy/randomdict

Possui acesso aleatório O (1) a chaves, valores e itens.

Rob T
fonte
19
não é O (1) para encontrar a sua resposta real
Berry Tsakala
14

Tente o seguinte:

import random
a = dict(....) # a is some dictionary
random_key = random.sample(a, 1)[0]

Isso definitivamente funciona.

lavee_singh
fonte
12

Se você não quiser usar o randommódulo, também pode tentar popitem () :

>> d = {'a': 1, 'b': 5, 'c': 7}
>>> d.popitem()
('a', 1)
>>> d
{'c': 7, 'b': 5}
>>> d.popitem()
('c', 7)

Como a dict ordem não preserva , usando popitemvocê obtém itens em uma ordem arbitrária (mas não estritamente aleatória).

Lembre-se também de que popitemremove o par de valores-chave do dicionário, conforme indicado nos documentos .

popitem () é útil para iterar destrutivamente sobre um dicionário

patriciasz
fonte
29
Isso é meio ruim, porque se você carregar o dicionário na mesma ordem na mesma versão do python, quase certamente obterá o mesmo item.
22414 Alex
Veja também: stackoverflow.com/questions/10593651/…
Ciro Santilli (
31
python 3.6 dict está realmente ordenado ! Isso é super importante
Ou Duan
7
Esta resposta está errada. Mesmo antes da versão 3.6, isso não fornecerá um valor aleatório, mas um valor dependendo do valor do hash do item.
Obu
1
Ignorando a incongruência com a solicitação do OP, essa é uma boa maneira de superar o fato de que nextnão funciona com um dicionário, pois é um mapeamento. (Eu vim aqui para inspiração e foi isso).
9118 Matteo Ferla
9
>>> import random
>>> d = dict(Venezuela = 1, Spain = 2, USA = 3, Italy = 4)
>>> random.choice(d.keys())
'Venezuela'
>>> random.choice(d.keys())
'USA'

Chamando random.choice no keysdicionário (os países).

user225312
fonte
2
Oi, eu tento usar seu método para escolher aleatoriamente uma chave de um determinado dicionário, mas não funciona. Meu dicionário se parece com a = {'walk': 20, 'run': 80} e quando eu uso random.choice (a.keys ()), ocorre um erro como "o objeto dict_keys 'não suporta indexação". Você sabe o que há de errado? Muito obrigado!!!
Beepretty
7
@beepretty dict.keys () retorna um objeto iterável, não um objeto de lista. Para resolver o erro, use random.choice(list(d.keys())).
galho verde
3
Em vez disso, use random.sample, que é mais barato do que copiar as chaves de uma lista.
steveayre
7

Isso funciona no Python 2 e Python 3:

Uma chave aleatória:

random.choice(list(d.keys()))

Um valor aleatório

random.choice(list(d.values()))

Uma chave e valor aleatórios

random.choice(list(d.items()))
firelynx
fonte
4

Se você não quiser usar o random.choice (), tente o seguinte:

>>> list(myDictionary)[i]
'VENEZUELA'
>>> myDictionary = {'VENEZUELA':'CARACAS', 'IRAN' : 'TEHRAN'}
>>> import random
>>> i = random.randint(0, len(myDictionary) - 1)
>>> myDictionary[list(myDictionary)[i]]
'TEHRAN'
>>> list(myDictionary)[i]
'IRAN'
Milad Mohammad Rezaei
fonte
Preste atenção: você gera um list(…)aqui várias vezes. Que tal myDictionary_list = list(myDictionary)?
Cadoiz 10/07
4

Como o post original queria o par :

import random
d = {'VENEZUELA':'CARACAS', 'CANADA':'TORONTO'}
country, capital = random.choice(list(d.items()))

(estilo python 3)

OBu
fonte
3

Como isso é lição de casa:

Confira o random.sample()que selecionará e retornará um elemento aleatório de uma lista. Você pode obter uma lista de chaves de dicionário com dict.keys()e uma lista de valores de dicionário com dict.values().

carl
fonte
5
random.samplee random.choicenão pode trabalhar com iteradores. Eles precisam saber o comprimento da sequência, que não pode ser determinado a partir de um iterador.
AFoglia
10
não, isso não é lição de casa, estou escrevendo para me ajudar com o espanhol.
#
3
random.sampleretorna elementosk aleatórios , retorna um único elemento aleatóriorandom.choice
Anentropic
Sim ... nunca é legal assumir que este é um problema de lição de casa. O que dizer isso faz pela comunidade?
jvriesem
3

Estou assumindo que você está fazendo um tipo de aplicativo de teste. Para esse tipo de aplicativo, escrevi uma função que é a seguinte:

def shuffle(q):
"""
The input of the function will 
be the dictionary of the question
and answers. The output will
be a random question with answer
"""
selected_keys = []
i = 0
while i < len(q):
    current_selection = random.choice(q.keys())
    if current_selection not in selected_keys:
        selected_keys.append(current_selection)
        i = i+1
        print(current_selection+'? '+str(q[current_selection]))

Se eu vou dar a entrada questions = {'VENEZUELA':'CARACAS', 'CANADA':'TORONTO'}e chamar a funçãoshuffle(questions) a saída será a seguinte:

VENEZUELA? CARACAS
CANADÁ? TORONTO

Você pode estender ainda mais isso misturando as opções também

Anivarth
fonte
Você não deve programar desenho sem substituição como esta. Imagine desenhar o 100º dos 100 elementos - 99% de chance de atingir um elemento dentro dele selected_keys. E você provavelmente repetirá isso cerca de 100 vezes. Pelo menos apague as teclas capturadas de q like del(q[current_selection])- você pode sobrescrever q com o novo shuffled selected_keyscomo q = selected_keysdepois de tudo. Também não se esqueça de identificar! Como alternativa, observe minha np.random.choice(...)abordagem: stackoverflow.com/a/62843377/4575793
Cadoiz 10/07
1

Tente isso (usando random.choice dos itens)

import random

a={ "str" : "sda" , "number" : 123, 55 : "num"}
random.choice(list(a.items()))
#  ('str', 'sda')
random.choice(list(a.items()))[1] # getting a value
#  'num'
Herman Yanush
fonte
1

Com versões modernas de Python (desde 3), a objetos retornados por métodos dict.keys(), dict.values()e dict.items()são vista objetos *. E ei, pode ser iterado, portanto, o uso direto random.choicenão é possível, pois agora eles não são uma lista ou conjunto.

Uma opção é usar a compreensão da lista para fazer o trabalho com random.choice:

import random

colors = {
    'purple': '#7A4198',
    'turquoise':'#9ACBC9',
    'orange': '#EF5C35',
    'blue': '#19457D',
    'green': '#5AF9B5',
    'red': ' #E04160',
    'yellow': '#F9F985'
}

color=random.choice([hex_color for color_value in colors.values()]

print(f'The new color is: {color}')

Referências:

Israel Z. DelaMora
fonte
0
b = { 'video':0, 'music':23,"picture":12 } 
random.choice(tuple(b.items())) ('music', 23) 
random.choice(tuple(b.items())) ('music', 23) 
random.choice(tuple(b.items())) ('picture', 12) 
random.choice(tuple(b.items())) ('video', 0) 
ziya efkar
fonte
2
Bem-vindo ao Stack Overflow! Obrigado por este trecho de código, que pode fornecer ajuda limitada a curto prazo. Uma explicação adequada melhoraria bastante seu valor a longo prazo, mostrando por que essa é uma boa solução para o problema e a tornaria mais útil para futuros leitores com outras perguntas semelhantes. Por favor edite sua resposta para adicionar alguma explicação, incluindo as suposições que você fez.
precisa saber é o seguinte
0

Encontrei este post procurando uma solução comparável. Para escolher vários elementos de um dict, isso pode ser usado:

idx_picks = np.random.choice(len(d), num_of_picks, replace=False) #(Don't pick the same element twice)
result = dict ()
c_keys = [d.keys()] #not so efficient - unfortunately .keys() returns a non-indexable object because dicts are unordered
for i in idx_picks:
    result[c_keys[i]] = d[i]
Cadoiz
fonte