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?

tekknolagi
la source

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()))
Gerrat
la source
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
26

J'ai écrit ceci en essayant de résoudre le même problème:

https://github.com/robtandy/randomdict

Il a un accès aléatoire O (1) aux clés, valeurs et éléments.

Rob T
la source
19
ce n'est pas O (1) pour trouver votre réponse réelle
Berry Tsakala
14

Essaye ça:

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

Cela fonctionne vraiment.

lavee_singh
la source
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

Patriciasz
la source
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
Voir aussi: stackoverflow.com/questions/10593651/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
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).

user225312
la source
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()))
firelynx
la source
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'
Milad Mohammad Rezaei
la source
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)

OBu
la source
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().

Carl
la source
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

Anivarth
la source
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'
Herman Yanush
la source
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:

Israël Z. DelaMora
la source
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
la source
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]
Cadoiz
la source