Jak uzyskać losową wartość ze słownika w Pythonie


149

Jak mogę uzyskać losową parę z dict? Tworzę grę, w której musisz odgadnąć stolicę kraju, a pytania powinny pojawiać się losowo.

Że dictwygląda jak{'VENEZUELA':'CARACAS'}

W jaki sposób mogę to zrobić?

Odpowiedzi:


260

Jednym ze sposobów byłoby:

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

EDYCJA : Pytanie zostało zmienione kilka lat po oryginalnym poście i teraz dotyczy pary zamiast pojedynczego elementu. Ostatnia linia powinna teraz wyglądać następująco:

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

141
To zadziała w Pythonie 2.x, gdzie d.keys()jest listą, ale nie zadziała w Pythonie 3.x, gdzie d.keys()jest iteratorem. Zamiast tego powinieneś to zrobić random.choice(list(d.keys())).
Duncan

21
@Duncan: Nie mogę się doczekać, aż wszystkie biblioteki innych firm będą zgodne z Pythonem 3.x, więc pytania Pythona nie wymagają 2 odpowiedzi na każde pytanie.
Gerrat

9
Eee, co powiesz na: d = {'VENEZUELA':'CARACAS', 'CANADA':'OTTAWA'}hehe, +1 za bardzo subtelne pranie mózgu ...
gentimouton

4
@gentimouton ... ciekawe, ale może po prostu wybierałem się do najbardziej zaludnionego miasta w każdym kraju - nie do stolic :)
Gerrat

12
Czy to jest wydajne? Czy ta skala, jeśli dykt staje się naprawdę duży?
Spectral


14

Spróbuj tego:

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

To zdecydowanie działa.


12

Jeśli nie chcesz używać randommodułu, możesz również spróbować popitem () :

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

Ponieważ dict nie zachowuje porządku , używając go popitemotrzymujesz z niego przedmioty w dowolnej (ale nie ściśle losowej) kolejności.

Pamiętaj też, że popitempowoduje to usunięcie pary klucz-wartość ze słownika, zgodnie z opisem w dokumentacji .

popitem () jest przydatna do destrukcyjnego iterowania po słowniku


29
To trochę źle, ponieważ jeśli załadujesz słownik w tej samej kolejności na tę samą wersję Pythona, prawie na pewno otrzymasz ten sam element.
Alex


31
python 3.6 dict jest faktycznie ZAMÓWIONY ! To jest bardzo ważne
albo Duan

7
Ta odpowiedź jest po prostu błędna. Nawet przed 3.6 nie da ci to losowej wartości, ale wartość zależną od wartości skrótu przedmiotu.
OBu

1
Ignorując niezgodność z żądaniem PO, ten sposób jest dobrym sposobem na obejście faktu, że nextnie działa ze słownikiem, ponieważ jest to mapowanie. (Przyszedłem tu po inspirację i to było to).
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'

Wywołując random.choice na keyssłownika (państwa).


2
Cześć, próbuję użyć Twojej metody, aby losowo wybrać jeden klucz z danego słownika, ale to nie działa. Mój słownik wygląda jak a = {'walk': 20, 'run': 80} i kiedy używam random.choice (a.keys ()), pojawia się błąd, taki jak „obiekt dict_keys” nie obsługuje indeksowania ”. Czy wiesz, co się stało? Wielkie dzięki!!!
beepretty

7
@beepretty dict.keys () zwraca obiekt iterowalny, a nie obiekt podobny do listy. Aby rozwiązać problem, użyj random.choice(list(d.keys())).
Greenstick

3
Zamiast tego użyj random.sample, co jest tańsze niż kopiowanie kluczy do listy.
steveayre

7

Działa to w Pythonie 2 i Pythonie 3:

Losowy klucz:

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

Wartość losowa

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

Losowy klucz i wartość

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

4

Jeśli nie chcesz używać random.choice (), możesz spróbować w ten sposób:

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

Uwaga: generujesz list(…)tutaj wiele razy. A co powiesz myDictionary_list = list(myDictionary)?
Cadoiz

4

Ponieważ oryginalny post chciał pary :

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

(w stylu pythona 3)


3

Ponieważ to jest praca domowa:

Sprawdź, random.sample()co wybierze i zwróci losowy element z listy. Możesz uzyskać listę kluczy słownika za pomocą dict.keys()i listę wartości słownika za pomocą dict.values().


5
random.samplei random.choicenie może pracować z iteratorami. Muszą znać długość sekwencji, której nie można określić na podstawie iteratora.
AFoglia

10
nie, to NIE jest praca domowa. Piszę ją, aby pomóc mi z hiszpańskim.
tekknolagi

3
random.samplezwraca elementyk losowe , zwraca pojedynczy element losowyrandom.choice
Anentropic

Tak ... nigdy nie fajnie zakładać, że to problem z pracą domową. Co powiedzenie to dla społeczności?
jvriesem

3

Zakładam, że tworzysz aplikację typu quiz. Dla tego rodzaju aplikacji napisałem funkcję, która wygląda następująco:

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

Jeśli podam dane wejściowe questions = {'VENEZUELA':'CARACAS', 'CANADA':'TORONTO'}i wywołam funkcję, shuffle(questions)to wynik będzie następujący:

WENEZUELA? CARAKAS
KANADA? TORONTO

Możesz to jeszcze bardziej rozszerzyć, tasując również opcje


Nie powinieneś programować rysowania bez zamiany w ten sposób. Wyobraź sobie, że rysujesz setną ze 100 elementów - 99% szans na trafienie elementu wewnątrz selected_keys. Prawdopodobnie powtórzysz to około 100 razy. Przynajmniej usuń zabrane klawisze q jak del(q[current_selection])- możesz nadpisać q nowym przetasowanym, selected_keystak jak q = selected_keyspo wszystkim. Nie zapomnij też o identyfikacji! Alternatywnie spójrz na moje np.random.choice(...)podejście: stackoverflow.com/a/62843377/4575793
Cadoiz

1

Spróbuj tego (używając random.choice z pozycji)

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

Z nowoczesnych wersjach Pythona (od 3), obiektów zwróconych przez metod dict.keys(), dict.values()a dict.items()to widok obiektów *. I hej można iterować, więc bezpośrednie użycie random.choicenie jest możliwe, ponieważ teraz nie są one listą ani zestawem.

Jedną z opcji jest użycie listy ze zrozumieniem, aby wykonać zadanie z 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}')

Bibliografia:


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
Witamy w Stack Overflow! Dziękujemy za ten fragment kodu, który może zapewnić ograniczoną krótkoterminową pomoc. Właściwe wyjaśnienie znacznie poprawiłoby jego długoterminową wartość, pokazując, dlaczego jest to dobre rozwiązanie problemu, i uczyniłoby go bardziej użytecznym dla przyszłych czytelników z innymi, podobnymi pytaniami. Proszę edytować swoją odpowiedź dodać kilka wyjaśnień, w tym założeń już wykonanych.
Toby Speight

0

Znalazłem ten post szukając raczej porównywalnego rozwiązania. Aby wybrać wiele elementów z dyktu, można tego użyć:

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]
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.