所以我有一个列表,我想把这些值 "分配 "到一个不同的随机值。
例如
list = ["dog", "cat", "rat", "bird", "monkey"]
我想输出如下
{"dog": "bird", "cat": "monkey", "rat": "dog", "bird": "rat", "monkey": "cat"}
我想要的是
我试过这段代码,但很乱,我觉得这不是最好的方法。
def shuffle_recur(_list):
final = {}
not_done = copy.deepcopy(_list)
for value in _list:
without_list = not_done.copy()
if value in without_list :
without_list.remove(value)
if value in final.values():
for final_key, final_value in final.items():
if final_value == value:
print(final_value, ' ', final_key)
if final_key in without_list :
without_list.remove(final_key)
if len(without_list) < 1:
print('less')
return shuffle_recur(_list)
target = random.choice(without_list)
not_done.remove(target)
final[value] = target
print('{} >> {}'.format(value, target))
return final
但它很乱,我不认为这是最好的方法。 有什么更好的方法吗?
你可以只建立一个随机排序的项目列表,然后将它们作为键值配对。
从一方面你将采取的列表,在另一方面相同的列表旋转从上项 values[1:] + [values[0]]
你将两者压缩成2乘2的对子,并从这些对子中建立一个听写器
values = ["dog", "cat", "rat", "bird", "monkey"]
shuffle(values)
result = dict(zip(values, values[1:] + [values[0]]))
例子
洗牌 ['bird', 'dog', 'rat', 'monkey', 'cat']
旋转产生 ['dog', 'rat', 'monkey', 'cat', 'bird']
拉链 [('bird', 'dog'), ('dog', 'rat'), ('rat', 'monkey'), ('monkey', 'cat'), ('cat', 'bird')]
那么每一对都会成为一个映射
print(values) # ['bird', 'dog', 'rat', 'monkey', 'cat']
print(result) # {'bird': 'dog', 'dog': 'rat', 'rat': 'monkey', 'monkey': 'cat', 'cat': 'bird'}
如果你不想让映射互相跟随,只需用以下方法 shuffle
二次
mappings = list(zip(values, values[1:] + [values[0]]))
shuffle(mappings)
result = dict(mappings)
你可以对数据进行洗牌,然后随机生成周期长度来连接元素,直到你的列表用完为止。对于5个或更少元素的列表,需要创建一个全长的循环,以满足所有的要求(不能拆成4+1,因为1个元素没有伙伴,也不能拆成3+2,因为2个元素需要映射到自己身上,因此违反了要求#3)。对于长度为>=6的列表,我们可以随机选择最小长度为3的子周期。
import random
def random_mapping(data):
data = data.copy()
random.shuffle(data)
result = {}
while len(data) >= 5:
index = random.randint(3, len(data)-2) # length of the (sub-)cycle
if index == len(data)-2: # this means a full cycle is generated
index = len(data)
cycle, data = data[:index], data[index:]
result.update(zip(cycle, cycle[1:]))
result[cycle[-1]] = cycle[0]
return result
# used for shuffling
import random
def shuffle_recur(list1):
# the final dictionary
final = {}
# needed for values as list1 are the keys
list2 = copy.deepcopy(list1)
random.shuffle(list2)
# loop trough and assign values
for i in range(len(list1)):
final[list1[i]] = list2[i]
return final
你可以使用下面的:
ll = ["dog", "cat", "rat", "bird", "monkey"]
res = list(zip(ll, ll[1:] + ll[:1]))
print(dict(res))
# {'dog': 'cat', 'cat': 'rat', 'rat': 'bird', 'bird': 'monkey', 'monkey': 'dog'}
zip
函数可以用来提取列表上的对,而切片可以用来将当前元素与下一个元素连续配对,以实现高效配对。
你可以用简单的索引运算来实现。
>>> li=["dog", "cat", "rat", "bird", "monkey"]
>>> dict((li[i],li[(i+1)%len(li)]) for i in range(len(li)))
{'dog': 'cat', 'cat': 'rat', 'rat': 'bird', 'bird': 'monkey', 'monkey': 'dog'}
或者,用同样的算术来理解听写。
{li[i]:li[(i+1)%len(li)] for i in range(len(li))}
# same result
你可能需要做 li
一组来重复复制,您可以使用 洗牌 如果你想要一个随机的顺序。
进一步解释。
dict
创建一个字典,在本例中是由一个生成器创建元组。(li[i],li[(i+1)%len(li)])
取列表中的两个元素并创建一个元组。列表中取两个元素并创建一个元组。%len(li)
绕到 0
在列表末尾,所以你有 ('dog','cat'),('cat','rat')...
(li[last_element], li[first_element])
因为 li[(i+1)%len(li)]
算术。