我正试图从字典中选择一个随机值。然后从同一个字典中选择第二个值。保证它是不同的。
def pick_value():
value, attribute = random.choice(list(my_dict.items()))
return(value, attribute)
如果我调用它的功能,但是不能保证第二次调用它时,值会与第一次不同,所以我尝试了以下内容。
my_value_list = []
val1, attr1 = pick_value()
my_value_list.append(val1)
val2, attr2 = pick_value()
if val2 in my_value_list:
val2, attr2 = pick_value()
我偶尔会得到匹配的值。我尝试用if val2 in
替换while val2 in
语句但仍然没有运气。我误解了一些简单的事情吗?
答案 0 :(得分:7)
如果您需要两个值(或事先知道的任何固定数字),请使用random.sample()
。这就是它的用途:采样"没有替换",即一旦你从列表中选择了一个元素,就不再可以再次选择它了。
samples = random.sample(list(mydict.items()), 2)
attr1, val1 = samples[0]
attr2, val2 = samples[1]
答案 1 :(得分:2)
正如alexis
建议的那样,random.sample()
是这项工作的正确工具,但为了完整起见,如果你需要以迭代/懒惰的方式获取随机字段,你可以做它自己:
def pick_random_destructive(data):
key = random.choice(data.keys()) if data else None
return key, data.pop(key, None)
但是,这将修改您传递给它的dict
。如果您想要一个非修改的迭代方法,您可以创建一个生成器,如:
def pick_random_nondestructive(data):
keys = random.shuffle(data.keys())
while keys:
key = keys.pop()
yield key, data[key]
答案 2 :(得分:1)
random.choice
可以实现这一点,但是在每次调用函数后你都需要保留状态信息,因为当random.choice
返回先前的随机值时,你忽略该值并调用它再次。从序列中弹出值是另一种选择:
def pick_value():
L = list(my_dict.items())
if hasattr(pick_value, 'prev'):
for _ in range(100):
res = random.choice(L)
if res != pick_value.prev:
pick_value.prev = res
return res
else:
res = random.choice(L)
pick_value.prev = res
return res
第一次拨打pick_value
时,没有以前的值,这就是外部if
语句的用途,它会检查是否存在以前的值并进行比较反对新选择的随机值。当None
未能在100次调用random.choice
后返回不等于前一个值的随机值时,此函数将返回random.choice
。
*当然,这只是主题的变体,其他用户提供了更简单的替代方案,因此您不一定需要使用上述逻辑包装random.choice
。
答案 3 :(得分:0)
如果您已经在使用numpy库,则此选项很有用:
考虑使用numpy中的random.choice:
import numpy as np
my_dict = {"a" : 1, "b": 2, "c": 3, "d" : 4}
#first, take two random key index from 0 to length
twoRandom = np.random.choice(list(my_dict.keys()),2,replace=False)
#then take the value of the key at index in the list
key1 = twoRandom[0]
key2 = twoRandom[1]
#finally, get the value
value1 = my_dict.get(key1)
value2 = my_dict.get(key2)