1

我将 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 流作业,其中映射器基本上会输出给定行上的所有对组合,这些组合将由化简器进一步处理。

我的问题实际上很简单:如何在 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 但无法正确地从中得到一些东西。有什么想法吗?

4

3 回答 3

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)
于 2012-05-14T20:05:13.393 回答
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))
于 2012-05-14T19:58:01.137 回答
2

琐碎有什么不好

for i, x in enumerate(L):
    for y in L[i+1:]:
        whatever(x, y)

?

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

于 2012-05-14T20:08:43.610 回答