首页 > 解决方案 > 有没有办法随机打乱 Python 字典中的键和值,但结果不能有任何原始键值对?

问题描述

我想打乱这个字典中的键值对,这样结果就没有原始的键值对。起始字典:

my_dict = {'A':'a',
           'K':'k',
           'P':'p',
           'Z':'z'}

不想要的结果示例:

my_dict_shuffled = {'Z':'a',
                    'K':'k', <-- Original key value pair
                    'A':'p',
                    'P':'z'}

想要的结果示例:

my_dict_shuffled = {'Z':'a',
                    'A':'k',
                    'K':'p',
                    'P':'z'}

我试过while循环和for循环但没有运气。请帮忙!提前致谢。

标签: python

解决方案


这是我从Numberphile 视频中学到的一个万无一失的算法:)

import itertools
import random

my_dict = {'A': 'a',
           'K': 'k',
           'P': 'p',
           'Z': 'z'}

# Shuffle the keys and values.
my_dict_items = list(my_dict.items())
random.shuffle(my_dict_items)
shuffled_keys, shuffled_values = zip(*my_dict_items)

# Offset the shuffled values by one.
shuffled_values = itertools.cycle(shuffled_values)
next(shuffled_values, None)  # Offset the values by one.

# Guaranteed to have each value paired to a random different key!
my_random_dict = dict(zip(shuffled_keys, shuffled_values))

免责声明(感谢提及,@jf328):这不会产生所有可能的排列!它只会产生恰好有一个“循环”的排列。简而言之,该算法永远不会给您以下结果:

   {'A': 'k',
    'K': 'a',
    'P': 'z',
    'Z': 'p'}

但是,我想您可以通过构建子周期的随机列表来扩展此解决方案:

(2, 2, 3) => concat(zip(*items[0:2]), zip(*items[2:4]), zip(*items[4:7]))

推荐阅读