2010-11-18 43 views
3

我的程序没有做得很好。在一个循环中,来自每个处理器的数据(元组列表)被收集到主处理器中,需要通过去除相似的元素来清除它。Performance_Python根据元组的3个元素中的2个得到2个元组列表的联合

我在互联网上发现了很多有趣的线索,尤其是在这个网站关于列表的联合。但是,我还没有设法将其应用于我的问题。 我的目标是摆脱其最后两个元素与列表中另一个元组相似的元组。例如:

list1=[[a,b,c],[d,e,f],[g,h,i]] 
list2=[[b,b,c],[d,e,a],[k,h,i]] 
the result should be: 
final=[[a,b,c],[d,e,f],[g,h,i],[d,e,a]] 

现在我正在使用循环并打破,但我希望能够使此过程更快。

这里是我的代码看起来像(结果和温度是我想要联合的列表) python2.6。

for k in xrange(len(temp)): 
    u=0 
    #index= next((j for j in xrange(lenres) if temp[k][1:3] == result[j][1:3]),None) 
    for j in xrange(len(result)): 
     if temp[k][1:3] == result[j][1:3]: 
      u=1 
      break 
    if u==0: 
    #if index is None: 
     result.append([temp[k][0],temp[k][1],temp[k][2]]) 

感谢您的帮助

埃尔韦

+0

顺便说一句,list'[...]'不是元组''(...)',两者之间的性能可能不同。 – 2010-11-24 04:59:18

回答

1

下面是我们的唯一身份用户的功能。它需要参数l(列表)和f(函数),返回删除重复项的列表(以相同的顺序)。重复的定义如下:b是一个iff f(b)== f(a)的重复。

def uniques(l, f = lambda x: x): 
    return [x for i, x in enumerate(l) if f(x) not in [f(y) for y in l[:i]]] 

我们定义lastTwo如下:

lastTwo = lambda x: x[-2:] 

对于您的问题,我们使用它,如下所示:

>>> list1 
[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i')] 
>>> list2 
[('b', 'b', 'c'), ('d', 'e', 'a'), ('k', 'h', 'i')] 
>>> uniques(list1+list2, lastTwo) 
[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i'), ('d', 'e', 'a')] 

如果你所描述的用例的时候,您可能需要定义很多

def hervesMerge(l1, l2): 
    return uniques(l1+l2, lambda x: x[-2:]) 

身份是我们的默认f,但它可以是任何东西(只要它是为列表中的所有元素定义的,因为它们可以是任何类型的)。

f可以是列表的总和,列表的奇数元素,整数的素数因子,任何东西。 (请记住,如果它的内射词没有意义,那么通过常量,线性函数等等的相加将不会与其他函数等同,因为它与f(x)== f(y)w/x!= y会产生差异)

>>> list1 
[(1, 2, 3, 4), (2, 5), (6, 2, 2), (3, 4), (8, 3), (1, 1, 1, 1, 1, 1, 1, 1, 1, 1)] 
>>> uniques(list1, sum) 
[(1, 2, 3, 4), (2, 5), (8, 3)] 
>>> uniques(list1, lambda x: reduce(operator.mul, x)) #product 
[(1, 2, 3, 4), (2, 5), (3, 4), (1, 1, 1, 1, 1, 1, 1, 1, 1, 1)] 
>>> uniques([1,2,3,4,1,2]) #defaults to identity 
[1, 2, 3, 4] 

您似乎对速度感到担忧,但我的回答确实关注的是短暂性/灵活性,而没有显着的(或任何?)速度改进。对于更大的名单,其中速度为z的关注,你想利用哈希的检查和事实列表1和列表2,已知有没有重复

>>> s = frozenset(i[-2:] for i in list1) 
>>> ans = list(list1) #copy list1 
>>> for i in list2: 
     if i[-2:] not in s: ans.append(i) 
>>> ans 
[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i'), ('d', 'e', 'a')] 

或允许无序

>>> d = dict() 
>>> for i in list2 + list1: 
     d[i[-2:]] = i 
>>> d.values() 
[('d', 'e', 'f'), ('a', 'b', 'c'), ('g', 'h', 'i'), ('d', 'e', 'a')] 

- 编辑 -

您应该始终能够避免像您在问题中发布的非pythonic循环。这是您与循环确切的代码改变:

for k in temp: 
    u=0 
    for j in result: 
     if k[1:3] == j[1:3]: 
      u=1 
      break 
    if u==0: 
    #if index is None: 
     result.append([k[0],k[1],k[2]]) // k 

结果和温度是可迭代的,而对于任何迭代,你可以把它直接在for循环不eanges。如果由于某种原因你明确需要索引(这不是这种情况,但我有一个上面的),你可以使用枚举。

+0

抱歉,如果我被带走了。我喜欢你的问题,并把它变成我自己的项目= P – 2010-11-18 04:28:57

+0

谢谢!使用拉姆达是我的想法,但我无法弄清楚如何做到这一点。 – herve 2010-11-19 00:24:58

+0

很高兴你喜欢。我发布了一个不同的解决方案,专注于速度的确切问题,这就是你问到的问题。你应该接受其中一个答案。除了勾住你接受的人之外,这将使人们更有可能在未来回答你。也会为你赢得一枚漂亮的徽章 – 2010-11-19 04:51:29

1

下面是使用一组简单的解决方案:

list1=[('a','b','c'),('d','e','f'),('g','h','i')] 
list2=[('b','b','c'),('d','e','a'),('k','h','i')] 

set1 = set([A[1:3] for A in list1]) 
final = list1 + [A for A in list2 if A[1:3] not in set1] 

但是,如果你的列表1和List2实际上不是由元组,那么你将不得不把元组()左右A [1:3] 。

+0

不幸的是,这一个不工作。 – herve 2010-11-19 02:19:24

+0

你确定吗? “最终”结果几乎就是你所期望的结果。它怎么不起作用? – 2010-11-19 05:13:16

+0

我的歉意......出于某种原因,当我将你的代码复制到我的python shell中时,我收到了错误消息。在阅读完您的消息之后,我再次尝试,正如您所说的那样。对不起,谢谢 – herve 2010-11-24 02:50:40

相关问题