Comment obtenir une valeur aléatoire du dictionnaire en python


149

Comment puis-je obtenir une paire aléatoire d'un dict? Je crée un jeu dans lequel vous devez deviner la capitale d'un pays et j'ai besoin de questions qui apparaissent au hasard.

Le dictressemble à{'VENEZUELA':'CARACAS'}

Comment puis-je faire ceci?

Réponses:


261

Une façon serait:

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

EDIT : La question a été modifiée quelques années après la publication d'origine, et demande maintenant une paire, plutôt qu'un seul élément. La dernière ligne devrait maintenant être:

country, capital = random.choice(list(d.items()))

141
Cela fonctionnera dans Python 2.x où d.keys()est une liste, mais cela ne fonctionnera pas dans Python 3.x où d.keys()est un itérateur. Tu devrais faire à la random.choice(list(d.keys()))place.
Duncan

21
@Duncan: J'ai hâte que toutes les bibliothèques tierces soient compatibles avec Python 3.x, donc les questions Python n'ont pas besoin de 2 réponses pour chaque question.
Gerrat

9
Euh que diriez-vous: d = {'VENEZUELA':'CARACAS', 'CANADA':'OTTAWA'}Hehe, +1 pour le lavage de cerveau très subtil ...
gentimouton

4
@gentimouton ... intéressant, mais peut-être que j'allais juste pour la ville la plus peuplée de chaque pays - pas les capitales :)
Gerrat

12
Est-ce efficace? Est-ce que cette échelle si dict devient vraiment grande?
Spectral


14

Essaye ça:

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

Cela fonctionne vraiment.


12

Si vous ne souhaitez pas utiliser le randommodule, vous pouvez également essayer popitem () :

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

Étant donné que l' dict ordre ne préserve pas , en utilisant, popitemvous obtenez des éléments dans un ordre arbitraire (mais pas strictement aléatoire).

Gardez également à l'esprit que popitemsupprime la paire clé-valeur du dictionnaire, comme indiqué dans la documentation .

popitem () est utile pour effectuer une itération destructive sur un dictionnaire


29
C'est un peu mauvais, car si vous chargez le dictionnaire dans le même ordre sur la même version de python, vous obtiendrez presque certainement le même élément.
Alex


31
python 3.6 dict est en fait ORDONNÉ ! C'est super important
Ou Duan

7
Cette réponse est tout simplement fausse. Même avant la version 3.6, cela ne vous donnera pas une valeur aléatoire, mais une valeur dépendant de la valeur de hachage de l'élément.
OBu

1
Ignorant l'incongruité avec la demande de l'OP, cette méthode est un bon moyen de surmonter le fait que nextcela ne fonctionne pas avec un dictionnaire car il s'agit d'une cartographie. (Je suis venu ici pour l'inspiration et c'était tout).
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'

En appelant random.choice sur le keysdu dictionnaire (les pays).


2
Salut, j'essaie d'utiliser votre méthode pour choisir au hasard une clé dans un dictionnaire donné, mais cela ne fonctionne pas. Mon dictionnaire ressemble à a = {'walk': 20, 'run': 80} et quand j'utilise random.choice (a.keys ()), il y a une erreur comme "l'objet dict_keys ne prend pas en charge l'indexation". Savez-vous ce qui ne va pas? Merci beaucoup!!!
beepretty

7
@beepretty dict.keys () renvoie un objet itérable, pas un objet de type liste. Pour résoudre l'erreur, utilisez random.choice(list(d.keys())).
Greenstick

3
Utilisez à la place random.sample, ce qui est moins cher que de copier les clés dans une liste.
steveayre

7

Cela fonctionne dans Python 2 et Python 3:

Une clé aléatoire:

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

Une valeur aléatoire

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

Une clé et une valeur aléatoires

random.choice(list(d.items()))

4

Si vous ne voulez pas utiliser random.choice (), vous pouvez essayer de cette façon:

>>> 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'

Faites attention: vous générez un list(…)ici plusieurs fois. Et pourquoi pas myDictionary_list = list(myDictionary)?
Cadoiz

4

Puisque le message original voulait la paire :

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

(style python 3)


3

Puisque ce sont des devoirs:

Vérifiez random.sample()qui sélectionnera et renverra un élément aléatoire dans une liste. Vous pouvez obtenir une liste de clés de dictionnaire avec dict.keys()et une liste de valeurs de dictionnaire avec dict.values().


5
random.sampleet random.choicene peut pas travailler avec des itérateurs. Ils ont besoin de connaître la longueur de la séquence, qui ne peut pas être déterminée à partir d'un itérateur.
AFoglia

10
non ce ne sont pas des devoirs je l'écris pour m'aider avec l'espagnol.
tekknolagi

3
random.samplerenvoie kdes éléments aléatoires , random.choicerenvoie un seul élément aléatoire
Anentropique

Ouais ... jamais cool de supposer que c'est un problème de devoirs. Qu'est-ce que cela fait pour la communauté?
jvriesem

3

Je suppose que vous faites une sorte d'application de quiz. Pour ce type d'application, j'ai écrit une fonction qui est la suivante:

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 je vais donner l'entrée questions = {'VENEZUELA':'CARACAS', 'CANADA':'TORONTO'}et appeler la fonction shuffle(questions), la sortie sera la suivante:

VENEZUELA? CARACAS
CANADA? TORONTO

Vous pouvez étendre cela davantage en mélangeant les options également


Vous ne devez pas programmer le dessin sans remplacement comme celui-ci. Imaginez dessiner le 100e des 100 éléments - 99% de chances de toucher un élément à l'intérieur de selected_keys. Et vous répéterez probablement cela environ 100 fois. Au moins, supprimez les touches prises de q comme del(q[current_selection])- vous pouvez écraser q avec le nouveau mélangé selected_keyscomme q = selected_keysaprès tout. N'oubliez pas non plus de vous identifier! Vous pouvez également regarder mon np.random.choice(...)approche: stackoverflow.com/a/62843377/4575793
Cadoiz

1

Essayez ceci (en utilisant random.choice from items)

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'

1

Avec les versions modernes de Python (depuis 3), les objets retournés par les méthodes dict.keys(), dict.values()et dict.items()sont des objets de vue *. Et bon peut être itéré, donc utiliser directement random.choicen'est pas possible car maintenant ils ne sont pas une liste ou un ensemble.

Une option consiste à utiliser la compréhension de liste pour faire le travail avec 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}')

Références:


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) 

2
Bienvenue dans Stack Overflow! Merci pour cet extrait de code, qui pourrait fournir une aide limitée à court terme. Une explication appropriée améliorerait considérablement sa valeur à long terme en montrant pourquoi c'est une bonne solution au problème, et la rendrait plus utile aux futurs lecteurs avec d'autres questions similaires. Veuillez modifier votre réponse pour ajouter des explications, y compris les hypothèses que vous avez formulées.
Toby Speight

0

J'ai trouvé ce post en cherchant une solution assez comparable. Pour sélectionner plusieurs éléments d'un dict, cela peut être utilisé:

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]
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.