Cómo obtener un valor aleatorio del diccionario en python

148

¿Cómo puedo obtener un par aleatorio de a dict? Estoy haciendo un juego en el que debes adivinar la capital de un país y necesito preguntas para que aparezcan al azar.

El dictparece{'VENEZUELA':'CARACAS'}

¿Cómo puedo hacer esto?

tekknolagi
fuente

Respuestas:

259

Una forma sería:

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

EDITAR : La pregunta se cambió un par de años después de la publicación original, y ahora pide un par, en lugar de un solo elemento. La línea final ahora debería ser:

country, capital = random.choice(list(d.items()))
Gerrat
fuente
141
Eso funcionará en Python 2.x donde d.keys()hay una lista, pero no funcionará en Python 3.x donde d.keys()hay un iterador. Deberías hacer en su random.choice(list(d.keys()))lugar.
Duncan
21
@Duncan: No puedo esperar hasta que todas las bibliotecas de terceros sean compatibles con Python 3.x, por lo que las preguntas de Python no necesitan 2 respuestas para cada pregunta.
Gerrat 01 de
9
Err ¿qué tal: d = {'VENEZUELA':'CARACAS', 'CANADA':'OTTAWA'}Jeje, +1 para el lavado de cerebro muy sutil ...
gentimouton
44
@gentimouton ... interesante, pero tal vez solo estaba yendo por la ciudad más poblada de cada país, no las capitales :)
Gerrat
12
¿Es esto eficiente? ¿Esta escala si dict se hace realmente grande?
Espectral
26

Escribí esto tratando de resolver el mismo problema:

https://github.com/robtandy/randomdict

Tiene O (1) acceso aleatorio a claves, valores y elementos.

Rob T
fuente
19
no es O (1) encontrar tu respuesta real
Berry Tsakala
14

Prueba esto:

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

Esto definitivamente funciona.

lavee_singh
fuente
12

Si no desea utilizar el randommódulo, también puede probar popitem () :

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

Como dict no conserva el orden , al usarlo popitemobtienes elementos en un orden arbitrario (pero no estrictamente aleatorio).

También tenga en cuenta que popitemelimina el par clave-valor del diccionario, como se indica en los documentos .

popitem () es útil para iterar destructivamente sobre un diccionario

patriciasz
fuente
29
Esto es algo malo, porque si carga el diccionario en el mismo orden en la misma versión de Python, seguramente obtendrá el mismo elemento.
Alex
Ver también: stackoverflow.com/questions/10593651/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
31
¡Python 3.6 dict está realmente ORDENADO ! Esto es súper importante
o Duan el
77
Esta respuesta es simplemente incorrecta. Incluso antes de 3.6, esto no le dará un valor aleatorio, sino un valor que depende del valor hash del elemento.
OBu
1
Ignorando la incongruencia con la solicitud del OP, esta es una buena manera de superar el hecho de que nextno funciona con un diccionario, ya que es un mapeo. (Vine aquí en busca de inspiración y esto fue todo).
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'

Llamando a random.choice en el keysdiccionario (los países).

usuario225312
fuente
2
Hola, trato de usar su método para elegir aleatoriamente una clave de un diccionario dado, pero no funciona. Mi diccionario se ve como a = {'walk': 20, 'run': 80} y cuando uso random.choice (a.keys ()), hay un error como "el objeto dict_keys 'no admite indexación". ¿Sabes lo que está mal? ¡¡¡Muchas gracias!!!
Beepretty
77
@beepretty dict.keys () devuelve un objeto iterable, no un objeto tipo lista. Para resolver el error, use random.choice(list(d.keys())).
Greenstick
3
Utilice random.sample en su lugar, que es más barato que copiar las claves en una lista.
steveayre
7

Esto funciona en Python 2 y Python 3:

Una clave aleatoria:

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

Un valor aleatorio

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

Una clave y un valor aleatorios

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

Si no quieres usar random.choice () puedes intentarlo de esta manera:

>>> 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
fuente
Presta atención: generas un list(…)aquí varias veces. ¿Qué tal myDictionary_list = list(myDictionary)?
Cadoiz
4

Como la publicación original quería la pareja :

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

(estilo python 3)

OBu
fuente
3

Como esto es tarea:

Vea random.sample()cuál seleccionará y devolverá un elemento aleatorio de una lista. Puede obtener una lista de claves de diccionario con dict.keys()y una lista de valores de diccionario con dict.values().

carl
fuente
55
random.sampley random.choiceno puede trabajar con iteradores. Necesitan saber la longitud de la secuencia, que no se puede determinar a partir de un iterador.
AFoglia 01 de
10
no, esto NO es tarea, la escribo para ayudarme con el español.
tekknolagi 01 de
3
random.sampledevuelve elementosk aleatorios , devuelve un único elemento aleatoriorandom.choice
Anentropic
Sí ... nunca es genial asumir que este es un problema de tarea. ¿Qué significa decir eso para la comunidad?
jvriesem
3

Supongo que está haciendo una aplicación de tipo cuestionario. Para este tipo de aplicación, he escrito una función que es la siguiente:

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]))

Si voy a dar la entrada de questions = {'VENEZUELA':'CARACAS', 'CANADA':'TORONTO'}y llamar a la funciónshuffle(questions) entonces la salida será la siguiente:

¿VENEZUELA? CARACAS
¿CANADÁ? TORONTO

Puede ampliar esto aún más barajando las opciones también

Anivarth
fuente
No debe programar el dibujo sin un reemplazo como este. Imagina dibujar el centésimo de 100 elementos: 99% de probabilidad de golpear un elemento dentro de él selected_keys. Y probablemente repetirás eso unas 100 veces. Al menos elimine las claves tomadas de q like del(q[current_selection]): puede sobrescribir q con el nuevo aleatorio selected_keyscomo q = selected_keysdespués de todo. ¡Tampoco te olvides de identificarte! Alternativamente, mira mi np.random.choice(...)enfoque: stackoverflow.com/a/62843377/4575793
Cadoiz
1

Prueba esto (usando random.choice de los elementos)

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
fuente
1

Con las versiones modernas de Python (desde 3), los objetos devueltos por métodos dict.keys(), dict.values()y dict.items()son objetos de vista *. Y bueno, se puede repetir, por random.choicelo que no es posible usarlo directamente , ya que ahora no son una lista o un conjunto.

Una opción es usar la comprensión de la lista para hacer el trabajo con 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}')

Referencias

Israel Z. DelaMora
fuente
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
fuente
2
¡Bienvenido a Stack Overflow! Gracias por este fragmento de código, que podría proporcionar una ayuda limitada a corto plazo. Una explicación adecuada mejoraría en gran medida su valor a largo plazo al mostrar por qué esta es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Por favor, editar su respuesta a añadir un poco de explicación, incluyendo los supuestos realizados.
Toby Speight
0

Encontré esta publicación buscando una solución bastante comparable. Para seleccionar múltiples elementos de un dict, esto se puede usar:

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
fuente