Как получить случайное значение из словаря в Python

149

Как я могу получить случайную пару от dict? Я делаю игру, в которой вам нужно угадать столицу страны, и мне нужно, чтобы вопросы появлялись случайным образом.

В dictсмахивает{'VENEZUELA':'CARACAS'}

Как я могу это сделать?

tekknolagi
источник

Ответы:

261

Одним из способов будет:

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

РЕДАКТИРОВАТЬ : вопрос был изменен через пару лет после первоначального сообщения, и теперь просит пару, а не один элемент. Последняя строка теперь должна быть:

country, capital = random.choice(list(d.items()))
Gerrat
источник
141
Это будет работать в Python 2.x, где d.keys()есть список, но не будет работать в Python 3.x, где d.keys()есть итератор. Вы должны сделать random.choice(list(d.keys()))вместо этого.
Дункан
21
@Duncan: я не могу дождаться, пока все сторонние библиотеки будут совместимы с Python 3.x, поэтому вопросы Python не требуют двух ответов на каждый вопрос.
Gerrat
9
О, как насчет: d = {'VENEZUELA':'CARACAS', 'CANADA':'OTTAWA'}Хе-хе, +1 за очень тонкое промывание мозгов ...
gentimouton
4
@gentimouton ... интересно, но, возможно, я просто собирался в самый густонаселенный город в каждой стране, а не в столицы :)
Gerrat
12
Это эффективно? Это масштабируется, если dict становится действительно большим?
Спектраль
26

Я написал это, пытаясь решить ту же проблему:

https://github.com/robtandy/randomdict

Он имеет O (1) произвольный доступ к ключам, значениям и элементам.

Роб Т
источник
19
это не O (1), чтобы найти ваш реальный ответ
Berry Tsakala
14

Попробуй это:

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

Это определенно работает.

lavee_singh
источник
12

Если вы не хотите использовать randomмодуль, вы также можете попробовать popitem () :

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

Поскольку dict порядок не сохраняет , используя его, popitemвы получаете элементы в произвольном (но не строго случайном) порядке.

Также имейте в виду, что popitemудаляет пару ключ-значение из словаря, как указано в документации .

popitem () полезен для деструктивного перебора словаря

patriciasz
источник
29
Это довольно плохо, потому что если вы загрузите словарь в том же порядке в той же версии Python, вы почти наверняка получите тот же элемент.
Алекс
См. Также: stackoverflow.com/questions/10593651/…
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
31
Python 3.6 DICT фактически заказан ! Это супер важно
Или Дуань
7
Этот ответ просто неверен. Даже до версии 3.6 это не даст вам случайное значение, а будет зависеть от значения хеша элемента.
OBu
1
Игнорируя несоответствие с запросом OP, этот способ является хорошим способом преодолеть тот факт, что nextне работает со словарем, так как это отображение. (Я пришел сюда для вдохновения, и это было все).
Маттео Ferla
9
>>> import random
>>> d = dict(Venezuela = 1, Spain = 2, USA = 3, Italy = 4)
>>> random.choice(d.keys())
'Venezuela'
>>> random.choice(d.keys())
'USA'

Позвонив random.choice на keysсловаре (страна).

user225312
источник
2
Привет, я пытаюсь использовать ваш метод, чтобы случайно выбрать один ключ из данного словаря, но он не работает. Мой словарь выглядит как a = {'walk': 20, 'run': 80}, и когда я использую random.choice (a.keys ()), возникает ошибка, такая как объект "dict_keys 'не поддерживает индексирование". Вы знаете, что не так? Большое спасибо!!!
beepretty
7
@beepretty dict.keys () возвращает итеративный объект, а не объект, подобный списку. Чтобы устранить ошибку, используйте random.choice(list(d.keys())).
Greenstick
3
Вместо этого используйте random.sample, который дешевле, чем копирование ключей в список.
Steveayre
7

Это работает в Python 2 и Python 3:

Случайный ключ:

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

Случайное значение

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

Случайный ключ и значение

random.choice(list(d.items()))
firelynx
источник
4

Если вы не хотите использовать random.choice (), вы можете попробовать это следующим образом:

>>> 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'
Милад Мохаммад Резаи
источник
Обратите внимание: вы генерируете list(…)здесь несколько раз. Как насчет myDictionary_list = list(myDictionary)?
Кадуиз
4

Так как оригинальный пост хотел пару :

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

(стиль Python 3)

OBu
источник
3

Так как это домашнее задание:

Проверьте, random.sample()какой из них выберет и вернет случайный элемент из списка. Вы можете получить список ключей словаря с помощью dict.keys()и список значений словаря с помощью dict.values().

деревенщина
источник
5
random.sampleи random.choiceне может работать с итераторами. Им нужно знать длину последовательности, которую нельзя определить с помощью итератора.
AFoglia
10
нет, это НЕ домашнее задание, я пишу это, чтобы помочь мне с испанским языком.
Tekknolagi
3
random.sampleвозвращает kслучайные элементы , random.choiceвозвращает один случайный элемент
Anentropic
Да ... никогда не бывает круто предположить, что это домашнее задание. Что говорят, что делают для сообщества?
jvriesem
3

Я предполагаю, что вы подаете заявку на викторину. Для такого рода приложений я написал следующую функцию:

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

Если я дам ввод questions = {'VENEZUELA':'CARACAS', 'CANADA':'TORONTO'}и вызову функцию, shuffle(questions)то вывод будет следующим:

ВЕНЕСУЭЛА? КАРАКАС
КАНАДА? ТОРОНТО

Вы можете расширить это еще больше, перетасовывая опции также

Anivarth
источник
Вы не должны программировать рисование без замены, как это. Представьте, что вы рисуете сотый из 100 элементов - 99% шанс попасть на элемент внутри selected_keys. И вы, вероятно, будете повторять это около 100 раз. По крайней мере удалите взятые ключи q like del(q[current_selection])- вы можете перезаписать q новым shuffled, selected_keysкак q = selected_keysпосле всего. Также не забывайте об идентификации! В качестве альтернативы посмотрите на мой np.random.choice(...)подход: stackoverflow.com/a/62843377/4575793
Cadoiz
1

Попробуйте это (используя random.choice из предметов)

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

В современных версиях Python (с 3), объекты , возвращаемые методами dict.keys(), dict.values()и dict.items()являются объектами вид *. И эй может быть повторен, поэтому использование напрямую random.choiceневозможно, так как теперь они не являются списком или набором.

Одним из вариантов является использование списка для выполнения работы с 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}')

Ссылки:

Израиль З. Деламора
источник
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
Добро пожаловать в стек переполнения! Спасибо за этот фрагмент кода, который может предоставить некоторую ограниченную краткосрочную помощь. Правильное объяснение значительно улучшило бы его долгосрочную ценность, показав, почему это хорошее решение проблемы, и сделало бы его более полезным для будущих читателей с другими, похожими вопросами. Пожалуйста, измените свой ответ, чтобы добавить некоторые объяснения, в том числе предположения, которые вы сделали.
Тоби Спейт
0

Я нашел этот пост, ища довольно сопоставимое решение. Для выбора нескольких элементов из условия, это может быть использовано:

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
источник