如何以随机顺序循环遍历Python字典中的项


D = {(1,1):2, (2,3):6, (3,4):12, (0,1):0, (4,9):36}
for (i,j),val in D.items():
print(i,j,"-->",val)

当我在字典的(key,value)对上循环时,顺序是确定的吗?我怎样才能按随机顺序循环它们?当字典很小时,下面的方法有效,但当有数千对时会导致内存错误。

from itertools import permutations
P = list(permutations(D.items()))
for (i,j),val in sample(P,1)[0]:
print(i,j,"-->",val)

在迭代条目之前对条目进行混洗应该相对简单。

from random import shuffle
dict_as_list_of_entries = [*D.items()]
shuffle(dict_as_list_of_entries) # randomizes the order
for (i, j), value in dict_as_list_of_entries:
# do something

这对于cpython3.6(python3.7(及更高版本来说是有意义的,因为字典会记住它们的插入顺序。在较低版本上,结果是不确定的(事实上,它比"不确定"更具吸引力,但这确实可以(。

注意,CCD_ 2的输出也可以通过对随机化器进行种子设定而具有确定性"真正的随机性"这仍然只是一个概念——尽管计算机已经接近实现它。大多数随机发生器例程是随机性和性能之间的折衷。

请注意,你之所以OOM'ing,是因为你正在生成字典中的每一个排列(而实际上你只想要一个,随机排列,而不是所有排列(。

当我在字典的(键,值(对上循环时,顺序是确定的吗?

这取决于您使用的Python版本。

  • 对于Python<3.6,顺序不一致,但不是真正随机的。对于不同的Python实现,它可能会有所不同,但对于两个不同的人或两次不同的运行,你不能指望它是相同的或不相同的
  • 对于Python 3.6(特别是CPython(,迭代顺序恰好与插入顺序相同,但仍然不是"正式地";保证
  • 对于Python>3.6,明确保证迭代顺序为插入顺序

如何以随机顺序循环它们?试着随机化密钥的顺序,然后循环这些密钥:

import random
shuffled_keys = random.sample(D.keys(), len(D.keys()))
for k in shuffled_keys:
print(f'{k} --> {D[k]}')

您可以制作一个字典键的混洗列表,然后对其进行迭代。这意味着您必须复制所有关键点,但可以避免复制值。根据字典中的内容,这可能会节省一些内存。

import random
d = {(1, 1): 2, (2, 3): 6, (3, 4): 12, (0, 1): 0, (4, 9): 36}
for key in random.sample(d.keys(), k=len(d)):
value = d[key]
i, j = key
print(i, j, "-->", value)

(免责声明:我还没有测试它是否真的比cs95的解决方案或其他解决方案节省了内存。关于内存使用和性能的直觉往往是错误的,所以你应该测试这个代码是如何处理你的数据的,看看它与其他解决方案相比如何。(

dict是一组无序的键值对。当您迭代dict时,它实际上是随机的。但是,要显式随机化键值对的序列,您需要使用不同的有序对象,如列表。dict.items((、dict.keys((和dict.values((都返回列表,这些列表可以被打乱。希望这能在任何方面帮助你

最新更新