How can I create a new list of tuples based on the values ​​from the original list of tuples?

My function is currently returning:

[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]

      

However, I want the final output:

[('a', 'h'), ('d', 'g')]

      

As you can see, if I [1] and I [2] are the same, I need me [0] to connect together.

I've tried to use a for loop, but I can't think of how to write it at the moment.

+3


source to share


5 answers


It works:



from itertools import combinations

l = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
print([(a[0], b[0]) for a, b in combinations(l, 2) if a[1:] == b[1:]])

      

+2


source


based on the second and third elements of each tuple, adding the first element to the list, then filtering out lists that are & lt; 1:

from collections import defaultdict

d = defaultdict(list)
for a,b,c in l:
    d[b,c].append(a)

print([tuple(val) for val in d.values() if len(val)>1])
[('a', 'h'), ('d', 'g')]

      



To ensure that the first order match is using OrderedDict:

from collections import OrderedDict
d = OrderedDict()
for a,b,c in l:
    d.setdefault((b,c),[]).append(a)

print([tuple(val) for val in d.values() if len(val)>1])

      

+1


source


You can do this by sorting the list based on the second and third elements and then using itertools.groupby

. Then, for each group, you can take the first elements from the elements within it. Example -

>>> a = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
>>> lst = []
>>> new_a = sorted(a, key=lambda i: (i[1], i[2]))
>>> for _, x in itertools.groupby(new_a, lambda i: (i[1], i[2])):
...     lst.append(tuple(y[0] for y in x))
...
>>> lst
[('a', 'h'), ('d', 'g')]

      


It can also be done in one line as (albeit unreadable) -

>>> l = [tuple(y[0] for y in x) for _, x in itertools.groupby(sorted(a, key=lambda i: (i[1], i[2])), lambda i: (i[1], i[2]))]
>>> l
[('a', 'h'), ('d', 'g')]

      

+1


source


I think this solution will preserve order (based on original location):

from itertools import groupby
from operator import itemgetter
from collections import defaultdict

x = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
groupings, seen_list=defaultdict(list), []

for key, value in groupby(x, itemgetter(1, 2)):
    if key not in seen_list:
         seen_list.append(key)
    groupings[key].extend(list(map(itemgetter(0),value)))

print([groupings[key] for key in seen_list])

      

If the order is not important, you can ignore the seen_list and just print the groupings.values ​​()

x = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
groupings=defaultdict(list)
for key, value in groupby(x, itemgetter(1, 2)):
    groupings[key].extend(list(map(itemgetter(0),value)))

print(groupings.values())

      

+1


source


Maybe not so pythonic, but a little simpler:

>>> a = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]    
>>> c = {}
>>> [c[j+k].append(i) if j+k in c else c.update({j+k:[i]}) for i,j,k in a]
>>> c = c.values()
>>> print c
[['d', 'g'], ['a', 'h']]

      

0


source







All Articles