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


149

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

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

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

Ответы:


261

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

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

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

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

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 становится действительно большим?
Спектраль


14

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

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

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


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 () полезен для деструктивного перебора словаря


29
Это довольно плохо, потому что если вы загрузите словарь в том же порядке в той же версии Python, вы почти наверняка получите тот же элемент.
Алекс


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словаре (страна).


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

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)


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)то вывод будет следующим:

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

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


Вы не должны программировать рисование без замены, как это. Представьте, что вы рисуете сотый из 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]
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.