如何在Python中以随机顺序遍历字典?

24

我如何以随机顺序迭代字典中的所有项?我的意思是类似于random.shuffle,但是用于字典。

5个回答

35

dict 是一个无序的键值对集合。当你迭代一个 dict 时,迭代的顺序是随机的。但是如果想要明确地随机排列键值对的顺序,需要使用另一个有序的对象,比如列表。dict.items()dict.keys()dict.values() 分别返回列表,可以进行洗牌。

items=d.items() # List of tuples
random.shuffle(items)
for key, value in items:
    print key, value

keys=d.keys() # List of keys
random.shuffle(keys)
for key in keys:
    print key, d[key]

或者,如果你不关心键:

values=d.values() # List of values
random.shuffle(values) # Shuffles in-place
for value in values:
    print value

你也可以通过“随机排序”:

for key, value in sorted(d.items(), key=lambda x: random.random()):
    print key, value

18
在Python3中,d.items()d.keys()d.values()生成迭代器对象。您需要使用list()函数显式地将该迭代器转换为列表。 - Charles Brunet
5
当你遍历一个字典时,并不是完全随机的,依赖它看起来是随机的想法是不好的,因为像整数这样的元素很可能按排序顺序出现。另外,随机键排序的时间复杂度为O(nlog(n)),而不是O(n),因此最好避免使用。 - user2357112
你如何调整代码以使字典始终被洗牌(同时保持正确的键与正确的值之间的链接,例如使用np.random.RandomState(100))? - Dhruv Ghulati

6
你无法直接打乱字典的键,但可以通过以下两种方法来实现:
1. 使用.keys()获取键的列表,打乱该列表,然后在遍历时使用原始字典的索引。
2. 使用.items()获取键值对的列表,打乱并在遍历时使用。

或者如果你只想要值,可以使用 dict.values() - Michael Hoffman
是不能还是不想?for item in random.sample(list(d.values()), len(d)): - SurpriseDog

0
import random

def main():

    CORRECT = 0

    capitals = {'Alabama': 'Montgomery', 'Alaska': 'Juneau',
        'Arizona': 'Phoenix', 'Arkansas': 'Little Rock'} #etc... you get the idea of a dictionary

    allstates = list(capitals.keys()) #creates a variable name and list of the dictionary items
    random.shuffle(allstates) #shuffles the variable

    for a in allstates: #searches the variable name for parameter
        studentinput = input('What is the capital of '+a+'? ')
        if studentinput.upper() == capitals[a].upper():
            CORRECT += 1
main()

0
我想要一种快速遍历洗牌列表的方法,所以我编写了一个生成器:
def shuffled(lis):
    for index in random.sample(range(len(lis)), len(lis)):
        yield lis[index]

现在我可以像这样遍历我的字典d
for item in shuffled(list(d.values())):
    print(item)

或者如果你想跳过创建一个新函数,这里有一个两行代码的解决方案:

for item in random.sample(list(d.values()), len(d)):
    print(item)

-1

正如Charles Brunet所说,字典是键值对的随机排列。但为了使它真正随机,您将使用随机模块。 我编写了一个函数,它将混洗所有的键,因此在您遍历它时,您将会随机遍历。您可以通过查看代码更清楚地理解:

def shuffle(q):
    """
    This function is for shuffling 
    the dictionary elements.
    """
    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
    return selected_keys

现在当您调用函数时,只需传递参数(您想要洗牌的字典名称),您将获得一个被洗牌的键列表。最后,您可以创建一个循环来遍历该列表的长度,并使用name_of_dictionary[key]来获取值。

最好使用现成的洗牌或排列函数,例如 numpy.random.permutation()。但如果你真的想自己做,这似乎是一种非常缓慢的洗牌方式!假设你有一个带有10,000个键的字典,并且你只剩下最后一个键。想象一下,在选择它之前你将不得不经历多少次失败的尝试!为了改进算法,您可以在每次迭代中从候选项中删除每个已选择的键,以便只从剩余的键中进行选择。 - Moot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接