列表中重叠对的Python组合

时间:2012-05-14 19:55:27

标签: python hadoop combinations

我正在运行一个Python脚本作为Hadoop流媒体作业,但这篇文章与一些核心Python概念有关,而不是关于Hadoop的知识。

基本上我有一组行,我想找到重叠

$ cat sample.txt
ID1    2143,2154,
ID2    2913,14545
ID3    2143,2390,3350,5239,6250
ID4    2143,2154,2163,3340
ID5    2143,2154,2156,2163,3340,3711

我想最终找到重叠的记录对并计算它们,例如:

2143,2154    3
2143,2163    2
2143,3340    2
2154,2163    2
2154,3340    2
2163,3340    2

我这样做的方法是创建一个用Python编写的Hadoop流作业,其中mapper将基本输出给定行上的所有对组合,并由reducer进一步处理。

我的问题实际上很简单:如何在Python中生成高效给定行中所有对的组合?请注意,在我的情况下,一对(x,y)与一对(y,x)相同。例如,对于ID3,我想在我的映射器中生成以下列表:

[(2143,2390), (2143,2390), (2143,3350), (2143,5239), (2143,6250), (2390,3350), (2390,5239), (2390,6250), (3350,5239), (3350,6250), (5239,6250)]

我当然可以通过一堆for循环来做到这一点,但它非常难看。我尝试过使用itertools,却无法正确使用它。有什么想法吗?

3 个答案:

答案 0 :(得分:8)

怎么样:

x = [2143, 2390, 3350, 5239, 6250]
itertools.combinations(x, 2)

给出:

(2143, 2390) (2143, 3350) (2143, 5239) (2143, 6250) (2390, 3350) (2390, 5239) (2390, 6250) (3350, 5239) (3350, 6250) (5239, 6250)

答案 1 :(得分:2)

如果l是有问题的列表

[(x, y) for x in l for y in l if x < y]

或者,您可以创建一个生成器:

def pairs(l):
  for x in l:
    for y in l:
      if x < y:
        yield x, y

这样做的好处是能够“动态”生成对,而不必同时将它们全部保存在内存中。

使用itertools.product(l, l)可以实现类似的功能,但这会生成(x, y) and (y, x),并且还会生成(x, x)之类的对。要过滤掉这些内容,您必须执行以下操作:

itertools.ifilter(lambda (x,y): x < y, itertools.product(l,l))

答案 2 :(得分:2)

琐碎的

有什么不对
for i, x in enumerate(L):
    for y in L[i+1:]:
        whatever(x, y)

这将调用whatever传递来自L的每个不同元素对(不同的意思是不同的索引,如果L包含重复项,它们可能相等)。