dheeraj
dheeraj

Reputation: 97

searching through a nested-list in python

I have a nested list of tuples of 97510 values like this:

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

every first value (index=0) is unique and I need to find other index=0 items that have the same index=1 items In the example , I need to find the second and third tuples where the the second item '4' is common .

How do I do it ?

Upvotes: 1

Views: 2106

Answers (4)

Artsiom Rudzenka
Artsiom Rudzenka

Reputation: 29093

Note that you can also use groupby:

from itertools import groupby

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

Edited as per comment

Played around with the problem and found one more solution - however not the best one, but:

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))

Upvotes: 1

Blair
Blair

Reputation: 15788

If you want to find all matches:

>>> 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)]

If you want to pick out all matches for a particular second value:

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

Edit: As pointed out in the comments, a list comprehension is preferable as it is more efficient for such work:

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

Using timeit shows the list comprehension is about 2.5 times faster (on my machine anyway):

>>> 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

Upvotes: 4

Rob Cowie
Rob Cowie

Reputation: 22619

Another alternative:

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)]

Upvotes: 1

Bj&#246;rn Pollex
Bj&#246;rn Pollex

Reputation: 76778

Here is one way to do it:

>>> 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)]})

This will result in a dictionary of lists where all items with the same second value are in one list, with that value as the key.

Upvotes: 3

Related Questions