组合两套并成对分割

时间:2011-11-26 23:55:55

标签: python tuples set

我需要从两组中获取两组数据并生成一组对(元组)。该结果集只有一个可能的对,即两个集: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而不是正确的结果。

这个函数需要使用整数和字符串(我不认为它需要按特定的顺序配对值),两个集合的值也会相等。

有人可以告诉我做错了吗?

4 个答案:

答案 0 :(得分:2)

错误告诉您发生了什么:pairsset,而表达式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)

您的家庭作业似乎是要实施zipproduct: - )

答案 1 :(得分:1)

如果您必须使用pop,请尝试同时弹出malesfemales,添加到pairs的元组中(顺便说一下,我不确定为什么你复制你的集合并销毁原件,但我想你有理由)。此外,迭代malesfemales将无法为您提供所需的答案 - 而是在您弹出时检查每个集合的空白。您正在寻找的更像是:

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,因此无法保证保留传入的malesfemales的任何订单

答案 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,您的方式无效。您在代码中所做的是您遍历所有男性和女性(复制参数后),然后从原始集中弹出项目。这样,很快,malesfemales这两个集合都将为空,因为您不断考虑每个可能的组合,而不考虑如果您继续重复使用单个项目,则只会获得所有组合。

您可以像这样修复代码,而不使用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