Come ottenere un valore casuale dal dizionario in Python


149

Come posso ottenere una coppia casuale da un dict? Sto realizzando un gioco in cui devi indovinare una capitale di un paese e ho bisogno che le domande appaiano casualmente.

Gli dictassomiglia{'VENEZUELA':'CARACAS'}

Come posso fare questo?

Risposte:


261

Un modo sarebbe:

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

EDIT : la domanda è stata cambiata un paio di anni dopo il post originale, e ora chiede una coppia, piuttosto che un singolo elemento. L'ultima riga dovrebbe ora essere:

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

141
Funzionerà in Python 2.x dove d.keys()è un elenco, ma non funzionerà in Python 3.x dove d.keys()è un iteratore. Dovresti random.choice(list(d.keys()))invece fare .
Duncan,

21
@Duncan: non vedo l'ora che tutte le librerie di terze parti siano compatibili con Python 3.x, quindi le domande di Python non hanno bisogno di 2 risposte per ogni domanda.
Gerrat,

9
Che ne dici di: d = {'VENEZUELA':'CARACAS', 'CANADA':'OTTAWA'}Hehe, +1 per il lavaggio del cervello molto sottile ...
gentimouton,

4
@gentimouton ... interessante, ma forse stavo andando per la città più popolosa di ogni paese - non le capitali :)
Gerrat

12
È efficiente? Questa scala se dict diventa davvero grande?
Spectral,


14

Prova questo:

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

Questo sicuramente funziona.


12

Se non vuoi usare il randommodulo, puoi anche provare popitem () :

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

Dal momento dict che non preserva l'ordine , usando popitempuoi ottenere oggetti in un ordine arbitrario (ma non strettamente casuale) da esso.

Inoltre, tieni presente che popitemrimuove la coppia chiave-valore dal dizionario, come indicato nei documenti .

popitem () è utile per iterare distruttivamente su un dizionario


29
Questo è un po 'brutto, perché se carichi il dizionario nello stesso ordine sulla stessa versione di Python avrai quasi sicuramente lo stesso oggetto.
Alex,


31
python 3.6 dict è in realtà ORDINATO ! Questo è molto importante
O Duan il

7
Questa risposta è sbagliata. Anche prima del 3.6 questo non ti darà un valore casuale, ma un valore che dipende dal valore di hash dell'oggetto.
OBu,

1
Ignorando l'incongruenza con la richiesta del PO, in questo modo è un buon modo per superare il fatto che nextnon funziona con un dizionario in quanto è una mappatura. (Sono venuto qui per l'ispirazione e questo è stato).
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'

Chiamando random.choice sul keysdizionario (i paesi).


2
Ciao, provo ad usare il tuo metodo per scegliere casualmente una chiave da un determinato dizionario, ma non funziona. Il mio dizionario sembra un = {'walk': 20, 'run': 80} e quando uso random.choice (a.keys ()), c'è un errore come "l'oggetto dict_keys non supporta l'indicizzazione". Sai cosa c'è che non va? Molte grazie!!!
beepretty,

7
@beepretty dict.keys () restituisce un oggetto iterabile, non un oggetto simile a un elenco. Per risolvere l'errore, utilizzare random.choice(list(d.keys())).
Greenstick,

3
Usa invece random.sample, che è più economico della copia delle chiavi in ​​un elenco.
Steveayre

7

Funziona in Python 2 e Python 3:

Una chiave casuale:

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

Un valore casuale

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

Una chiave e un valore casuali

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

4

Se non vuoi usare random.choice () puoi provare in questo modo:

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

Presta attenzione: generi un list(…)qui più volte. Che ne dici myDictionary_list = list(myDictionary)?
Cadoiz,

4

Dal momento che il post originale voleva la coppia :

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

(stile Python 3)


3

Dal momento che si tratta di compiti a casa:

Scopri random.sample()quale selezionerà e restituirà un elemento casuale da un elenco. È possibile ottenere un elenco di chiavi del dizionario con dict.keys()e un elenco di valori del dizionario con dict.values().


5
random.samplee random.choicenon può funzionare con iteratori. Devono conoscere la lunghezza della sequenza, che non può essere determinata da un iteratore.
AFoglia

10
no questo NON è un compito, lo sto scrivendo per aiutarmi con lo spagnolo.
tekknolagi,

3
random.samplerestituisce elementik casuali , restituisce un singolo elemento casualerandom.choice
Anentropico

Sì ... non è mai bello supporre che si tratti di un problema a casa. Cosa significa dire ciò per la comunità?
jvriesem,

3

Presumo che tu stia facendo un quiz tipo di domanda. Per questo tipo di applicazione ho scritto una funzione che è la seguente:

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 darò l'input di questions = {'VENEZUELA':'CARACAS', 'CANADA':'TORONTO'}e chiamerò la funzioneshuffle(questions) Quindi l'output sarà il seguente:

VENEZUELA? CARACAS
CANADA? TORONTO

Puoi estenderlo ulteriormente mescolando anche le opzioni


Non è necessario programmare il disegno senza sostituzione in questo modo. Immagina di disegnare il 100 ° di 100 elementi - 99% di probabilità di colpire un elemento all'interno di selected_keys. E probabilmente lo ripeterai circa 100 volte. Almeno cancella i tasti presi di q like del(q[current_selection])- puoi sovrascrivere q con il nuovo mischiato selected_keyscome q = selected_keysdopo tutto. Inoltre, non dimenticare di identificarti! In alternativa guardare il mio np.random.choice(...)approccio: stackoverflow.com/a/62843377/4575793
Cadoiz

1

Prova questo (usando random.choice dagli articoli)

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

Con le versioni moderne di Python (dal 3), gli oggetti restituiti con metodi dict.keys(), dict.values()e dict.items()sono oggetti vista *. Ehi possono essere ripetuti, quindi l'uso diretto random.choicenon è possibile in quanto ora non sono un elenco o un set.

Un'opzione è utilizzare la comprensione dell'elenco per eseguire il lavoro 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}')

Riferimenti:


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
Benvenuto in Stack Overflow! Grazie per questo frammento di codice, che potrebbe fornire un aiuto limitato a breve termine. Una spiegazione adeguata migliorerebbe notevolmente il suo valore a lungo termine mostrando perché questa è una buona soluzione al problema e lo renderebbe più utile ai futuri lettori con altre domande simili. Si prega di modificare la risposta di aggiungere qualche spiegazione, tra le ipotesi che hai fatto.
Toby Speight,

0

Ho trovato questo post cercando una soluzione piuttosto comparabile. Per selezionare più elementi da un dict, questo può essere usato:

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]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.