如何从字典中获得一个随机值?

如何从dict中获得一个随机对?我正在制作一款游戏,玩家需要猜测一个国家的首都,我需要随机出现问题。

dict看起来像{'VENEZUELA':'CARACAS'}

我该怎么做呢?

380321 次浏览

一种方法是:

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

编辑:在最初的帖子发布几年后,这个问题被改变了,现在要求一对,而不是一个项目。最后一行现在应该是:

country, capital = random.choice(list(d.items()))
>>> import random
>>> d = dict(Venezuela = 1, Spain = 2, USA = 3, Italy = 4)
>>> random.choice(d.keys())
'Venezuela'
>>> random.choice(d.keys())
'USA'

通过在字典的keys上调用random.choice(国家)。

因为这是家庭作业:

检查random.sample(),它将从列表中选择并返回一个随机元素。你可以用dict.keys()获取一个字典键列表,用dict.values()获取一个字典值列表。

如果你不想使用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从字典中删除键-值对,如文档. c中所述。

Popitem()用于对字典进行破坏性迭代

如果你不想使用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'

我写这篇文章是为了解决同样的问题:

https://github.com/robtandy/randomdict

它有O(1)对键、值和项的随机访问。

试试这个:

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

这绝对有效。

我假设你在做一个类似测验的应用程序。对于这种应用程序,我写了一个函数,如下所示:

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),那么输出将如下所示:

VENEZUELA? CARACAS
CANADA? TORONTO

您还可以通过调整选项进一步扩展此功能

试试这个(使用随机。物品选择)

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'

因为原来的帖子想要一对:

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

(python 3风格)

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)

这适用于Python 2和Python 3:

随机键:

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

一个随机值

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

一个随机键和值

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

在现代版本的Python中(从3开始),dict.keys()dict.values()dict.items()方法返回的对象是视图对象*。hey可以被迭代,所以直接使用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}')

引用:

我通过寻找一个相当类似的解决方案找到了这篇文章。如果要从字典中选取多个元素,可以使用:

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]

下面是一个字典类的Python代码,它可以在O(1)时间内返回随机键。(为了可读性,我在代码中包含了myypy类型):

from typing import TypeVar, Generic, Dict, List
import random


K = TypeVar('K')
V = TypeVar('V')
class IndexableDict(Generic[K, V]):
def __init__(self) -> None:
self.keys: List[K] = []
self.vals: List[V] = []
self.dict: Dict[K, int] = {}


def __getitem__(self, key: K) -> V:
return self.vals[self.dict[key]]


def __setitem__(self, key: K, val: V) -> None:
if key in self.dict:
index = self.dict[key]
self.vals[index] = val
else:
self.dict[key] = len(self.keys)
self.keys.append(key)
self.vals.append(val)


def __contains__(self, key: K) -> bool:
return key in self.dict


def __len__(self) -> int:
return len(self.keys)


def random_key(self) -> K:
return self.keys[random.randrange(len(self.keys))]

从字典集dict_data中选择50个随机键值:

sample = random.sample(set(dict_data.keys()), 50)

一种方法是:

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

编辑:在最初的帖子发布几年后,这个问题被修改了,现在是一对,而不是一个。最后一行现在应该是:

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

当他们要求随机配对时,他们指的是键和值。

对于这样一个字典,其中的关键:价值观是国家:城市,

使用random.choice()。

将字典键传递给这个函数,如下所示:

import random
keys = list(my_dict)
country = random.choice(keys)

您可能希望跟踪在一轮中已经调用的键,当获得一个新的国家时,循环直到随机选择不在那些已经“绘制”的列表中…只要绘制的列表比键列表短。

我只是偶然发现了一个类似的问题,并设计了以下解决方案(相关函数是pick_random_item_from_dict;其他函数只是为了完整性)。

import random




def pick_random_key_from_dict(d: dict):
"""Grab a random key from a dictionary."""
keys = list(d.keys())
random_key = random.choice(keys)
return random_key




def pick_random_item_from_dict(d: dict):
"""Grab a random item from a dictionary."""
random_key = pick_random_key_from_dict(d)
random_item = random_key, d[random_key]
return random_item




def pick_random_value_from_dict(d: dict):
"""Grab a random value from a dictionary."""
_, random_value = pick_random_item_from_dict(d)
return random_value


# Usage
d = {...}
random_item = pick_random_item_from_dict(d)

与之前答案的主要区别在于我们使用list(d.items())处理字典副本的方式。我们可以部分地绕过这个问题,方法是只复制d.keys(),然后使用随机键来选择它的关联值并创建我们的随机项。

我需要遍历dict 而不是每次都排序中的键范围,并找到排序的容器库。我发现这个库可以通过索引随机访问字典项,直观地解决了这个问题

>>> import sortedcontainers
>>> import random
>>> d = sortedcontainers.SortedDict({1: 'a', 2: 'b', 3: 'c'})
>>> random.choice(d.items())
(1, 'a')
>>> random.sample(d.keys(), k=2)
[1, 3]