我需要从两组中获取两组数据并生成一组对(元组)。该结果集只有一个可能的对,即两个集:1,2和3,4结果应该是:((1,3),(2,4))。完整的练习文本可以在这里找到:http://pastebin.com/mUaKV4G7
我需要使用pop来做到这一点。这是我到目前为止所做的:
def mating_pairs(males, females):
pairs = set()
tmp_males, tmp_females = males.copy(), females.copy()
for male in tmp_males:
for female in tmp_females:
pairs.add(males.pop())
pairs.add(females.pop())
zip(pairs[::2], pairs[1::2])
return pairs
此功能可以正常工作到达:
zip(pairs[::2], pairs[1::2])
没有它给出两个集合它们将它们组合在一起但是当我尝试使用zip将它们成对分割时我得到了这个错误:
'set' object is not subscriptable
这让我相信它在某个地方返回None而不是正确的结果。
这个函数需要使用整数和字符串(我不认为它需要按特定的顺序配对值),两个集合的值也会相等。
有人可以告诉我做错了吗?
答案 0 :(得分:2)
错误告诉您发生了什么:pairs
是set
,而表达式pairs[::2]
表示“集合的每个第2个元素”。问题是set
没有定义的顺序,因此“集合中的每个第二个元素”都没有意义。由于元素的顺序未定义,Python引发了异常,而不是构成随机顺序。
您可能想要做的是按照出现的顺序配对男性和女性:
def mating_pairs(males, females):
return zip(males, females)
或所有可能的男性和女性对(两个列表的产品):
from itertools import product
def mating_pairs(males, females):
return product(males, females)
您的家庭作业似乎是要实施zip
或product
: - )
答案 1 :(得分:1)
如果您必须使用pop,请尝试同时弹出males
和females
,添加到pairs
的元组中(顺便说一下,我不确定为什么你复制你的集合并销毁原件,但我想你有理由)。此外,迭代males
和females
将无法为您提供所需的答案 - 而是在您弹出时检查每个集合的空白。您正在寻找的更像是:
def mating_pairs(males, females):
pairs = set()
tmp_males, tmp_females = males.copy(), females.copy()
while tmp_males and tmp_females:
pairs.add((tmp_males.pop(),tmp_females.pop()))
return pairs
如果您可以避免使用set.pop
:
def mating_pairs(males, females):
return set(zip(males,females))
此外,请注意,除非您使用某种有序的set数据类型,否则这不是一个完整的答案。由于它使用的是set
,,因此无法保证保留传入的males
和females
的任何订单。
答案 2 :(得分:0)
如果强制限制使用pop
,我会选择类似的东西:
def mating_pairs(males, females):
res = set()
males_copy, females_copy = males.copy(), females.copy()
while males_copy and females_copy:
res.add((males_copy.pop(), females_copy.pop()))
return res
print mating_pairs(set([1, 2, 3]), set(['a', 'b', 'c', 'd']))
# => set([(1, 'a'), (2, 'b'), (3, 'c')])
但是set(zip(males, females))
无论如何都要容易得多。
答案 3 :(得分:0)
我有点不确定你想要做什么。但是分析你发布的代码,我想你想把每个男性和每个女性结合一次,并将每个组合的元组放入最终列表中。
如果是这种情况,那么您要做的就是创建Cartesian product。 Python库有一个很好的功能:itertools.product
。您可以像这样使用它:
def mating_pairs(males, females):
return set(itertools.product(males, females))
如果您想以手动方式执行此操作,则可以使用两个嵌套for循环来获取所有组合。但是,通过使用pop
,您的方式无效。您在代码中所做的是您遍历所有男性和女性(复制参数后),然后从原始集中弹出项目。这样,很快,males
和females
这两个集合都将为空,因为您不断考虑每个可能的组合,而不考虑如果您继续重复使用单个项目,则只会获得所有组合。
您可以像这样修复代码,而不使用pop:
def mating_pairs(males, females):
pairs = set()
# We only iterate over the items, so we don’t modify the original sets.
for male in males:
for female in females:
# And instead of adding individual items by once, and zipping them
# later, we just directly add tuples to the set.
pairs.add((male, female))
return pairs