从列表中创建随机配对

9
我正在尝试创建一个程序,用于打印列表中的元素对。我需要创建一个字典(一开始为空),以便存储值,循环遍历列表来创建一对并确保没有重复。
当我在列表中循环时,我需要获取一个随机数,并使用它来移除一个元素。使用pop方法从列表中删除随机选择的元素,将该元素存储到一个变量中,比如element1。重复此步骤以创建element2。
通过将element1插入pairs字典中作为键,并将其值设置为element2,将element1映射到element2,也就是说,如果我们稍后调用pairs[element1],它应该给出element2的值。
使用字典的items()和keys()方法打印结果。
问题是,我们只允许使用random模块中的random.randrange()函数 :(
示例如下:
list = ["Mother", "Father", "Aunt", "Uncle", "Brother", "Sister" ]

程序的样例运行,这会创建3对元素,因为列表中有6个元素。

Pair 1: Mother and Aunt
Pair 2: Uncle and Sister 
Pair 3: Brother and Father

这是我现在的程序:

family = ["Mother", "Father", "Aunt", "Uncle", "Brother", "Sister" ]

for x in family:


pairs = {}

我该如何改进/添加这段代码?

4
你需要获取一个随机数,但是不允许使用“random”模块吗?你的任务是编写自己的伪随机数生成器吗? - DSM
1
@DSM 或许这是个玩笑,学生们应该使用numpy.random。 - Carsten
1
你不能使用随机模块还是不允许使用它? - halex
是的,我不是很明白,我们可以使用随机模块,但唯一允许使用的函数是random.randrange。 - Tony Garangean
randrange 没问题,有什么问题吗? - Lee Daniel Crocker
显示剩余2条评论
4个回答

8
使用random.randrange从列表中选择(并删除)随机元素很容易:
def pop_random(lst):
    idx = random.randrange(0, len(lst))
    return lst.pop(idx)

假设列表中有偶数个元素,我们可以很容易地构建成对的元素:

pairs = []
while lst:
    rand1 = pop_random(lst)
    rand2 = pop_random(lst)
    pair = rand1, rand2
    pairs.append(pair)

您需要填写的内容还有两个步骤,我会留给您作为练习:

  1. 在开始之前确保列表是唯一的
  2. 确保唯一列表有偶数个元素(并找出如果没有偶数个元素应该做什么...)

你可以考虑使用 while len(lst) > 1,而不是 while lst,这样可以避免在处理奇数长度的列表时出现错误。 - Lee Daniel Crocker
@LeeDanielCrocker -- 那应该是给 OP 的一道练习题-- 我不想给出完整的答案 :-) - mgilson

2
import random

family = ["Mother", "Father", "Aunt", "Uncle", "Brother", "Sister" ]
pairs = {}

for p in range(len(family) // 2):
    pairs[p+1] = ( family.pop(random.randrange(len(family))),
        family.pop(random.randrange(len(family))) )

print(pairs)

你应该添加类似以下代码: for a in range(len(pairs)): print str(str(pairs.keys()[a]) + ' : ' + str(pairs.values()[a])) - Ben Morris

1

如果你想创建独特的配对,可以打乱数组的索引,然后每隔两个元素迭代遍历打乱后的数组。如果数组中的元素数量是偶数,则已完成。

import numpy as np

l = ["Mother", "Father", "Aunt", "Uncle", "Brother", "Sister" ]

indexes = list(range(0, len(l)))
np.random.shuffle(indexes)  # please note that shuffle is inplace

pairs = {}

for i in range(0, len(indexes), 2):
    pairs[l[i]] = l[i+1]

i = 1
for key, value in pairs.items():
    print(f'Pair {i}: {key} and {value}')
    i += 1

这是结果:

Pair 1: Mother and Father
Pair 2: Aunt and Uncle
Pair 3: Brother and Sister

1
同样的想法,但代码更少:random.shuffle(l); pairs = list(zip(*[iter(l)]*2)) - timgeb
@timgeb,你能把那个作为答案分享一下吗?谢谢 :) - user8395964

1
import random

l = ["Mother", "Father", "Aunt", "Uncle", "Brother", "Sister" ]

pairs = {}

while len(l) > 1:

    #Using the randomly created indices, respective elements are popped out
    r1 = random.randrange(0, len(l))
    elem1 = l.pop(r1)

    r2 = random.randrange(0, len(l))
    elem2 = l.pop(r2)

    # now the selecetd elements are paired in a dictionary 
    pairs[elem1] = elem2

#The variable 'pairs' is now a dictionary of this form:
#{'Sister': 'Aunt', 'Uncle': 'Father', 'Mother': 'Brother'}

##We can now print the elements of the dictionary in your desired format:
i = 1

for key, value in pairs.items():
    print("Pair {}: {} and {}".format(i, key, value))
    i += 1

当你运行它时,你应该看到类似这样的东西:
Pair 1: Sister and Aunt
Pair 2: Mother and Brother
Pair 3: Uncle and Father

1
如何打印出以下的内容: 组合 1:母亲和阿姨 组合 2:叔叔和姐妹 组合 3:兄弟和父亲 - Tony Garangean
1
我该如何添加最后一段代码?它说列表对象无法属性化。 - Tony Garangean
我在主体中添加了额外的代码。我测试了这段代码,现在它正常工作。我正在运行Python 3.4版本。只需按原样复制并粘贴代码,看看您是否仍然会收到错误提示。 - Omid

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