2011-06-20 202 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 –