2011-06-20 204 views
1

我有97510个值的元组的像这样的嵌套列表:搜索通过嵌套列表蟒蛇

a = [ (1,2,3), (3,4,5), (5,4,2)] 

每一个第一个值(指数= 0)是独一无二的,我需要找到其他的指数= 0具有相同索引的项目= 1项目 在此示例中,我需要查找第二个项目'4'常见的第二个和第三个元组。

我该怎么做?

回答

3

下面是做到这一点的一种方法:

>>> result = defaultdict(list) 
>>> for item in a: 
>>>  result[item[1]].append(item) 
>>> result 
defaultdict(<type 'list'>, {2: [(1, 2, 3)], 4: [(3, 4, 5), (5, 4, 2)]}) 

这将导致在列表中,因为具有相同第二值的所有项目都在一个列表中,以该值作为键的字典。

4

如果你想找到的所有匹配:

>>> from collections import defaultdict 
>>> d = defaultdict(list) 
>>> for inner in a: 
...  d[inner[1]].append(inner) 
... 
>>> d 
defaultdict(<type 'list'>, {2: [(1, 2, 3)], 4: [(3, 4, 5), (5, 4, 2)]}) 
>>> d[4] 
[(3, 4, 5), (5, 4, 2)] 

如果你想挑选出所有匹配特定第二个值:

>>> filter(lambda inner: inner[1] == 4, a) 
[(3, 4, 5), (5, 4, 2)] 

编辑:正如在评论中指出,列表理解是优选的,因为它是这样工作更有效率:

>>> [inner for inner in a if inner[1] == 4] 
[(3, 4, 5), (5, 4, 2)] 

使用timeit显示列表理解的约2.5倍的速度(在我的机器上是这样):

>>> timeit.timeit('[inner for inner in a if inner[1] == 4]', 'a=[(1,2,3), (3,4,5), (5, 4, 2)]') 
2.5041549205780029 
>>> timeit.timeit('filter(lambda inner: inner[1] == 4, a)', 'a=[(1,2,3), (3,4,5), (5, 4, 2)]') 
6.328679084777832 
+0

我一般会更喜欢'filter'与列表理解一个lambda - '[物品项目从一个if item [1] == 4]'。在我看来,阅读更好。 –

+0

@ Space_C0wb0y - 是的,我通常也会。不知道为什么我在这个答案中使用了过滤器。我已经用一些时间示例更新了它 - 以及更好的阅读,更快。 – Blair

1

请注意,您还可以使用groupby

from itertools import groupby 

data = [ (1,2,3), (3,4,5), (5,4,2)] 
res = groupby(sorted(data), key=lambda x: x[1]) 

市价修改意见

发挥各地的问题,发现多了一个解决方案 - 但不是最好的,但:

inputVals = [(1,2,3), (3,4,5), (5,4,2), (2,2,3), (7,3,1)] 
for val in set(x[1] for x in inputVals): 
    print val, list(set(sval for sval in inputVals if sval[1] == val)) 
+0

这只有在列表按键排序时才有效。 –

+0

当然,谢谢,我的回答只是简单地通知OP,他还有一个选项。 –

1

另一种选择:

from operator import itemgetter 
from itertools import groupby 

a = [ (1,2,3), (3,4,5), (5,4,2)] 
b = groupby(sorted(a), itemgetter(1)) 
for val, group in b: 
    print val, list(group) 
# 2 [(1, 2, 3)] 
# 4 [(3, 4, 5), (5, 4, 2)] 
+0

不错。我总是忘记itertools,它是我需要更多玩的东西。 – Blair

+0

首先对列表进行排序,然后遍历它。给O(n log n)的复杂度加上一个额外的通过列表。这不是有效的。 –

+0

@ Space_C0wb0y Yup –