繁体   English   中英

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

[英]How can I loop over the items of a Python dictionary in a random order?

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) 和更高版本是有意义的,因为字典会记住它们的插入顺序。 在较低版本上,结果不是确定性的(实际上,它比“非确定性”要麻烦一些,但这确实可以)。

请注意, shuffle的输出也可以通过为随机数设定种子来确定。 “真正的随机性”仍然只是一个概念——不过计算机已经接近实现它了。 大多数随机器例程是随机性和性能之间的权衡。

请注意,您正在 OOM,因为您正在生成字典的每一个排列(实际上您只想要一个随机排列,而不是全部)。

当我遍历字典的 (key,value) 对时,顺序是否确定?

这取决于您使用的 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() 每个返回列表,可以洗牌。 希望这能以任何方式帮助你

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM