I have a list of 3-tuples, and I want to split them on the last coordinate. So for example if the input were:
[(1,2,x), (2,3,x), (1,2,z), (2,20,z)]
I'd want the output to be
[(1,2,x),(2,3,x)],[(1,2,z),(2,20,z)]
My current approach involves getting all N distinct 3rd indices and looping over the list N times to build the list of lists. I am wondering if there is a pythonic way to do this without looping multiple times.
CodePudding user response:
here is one way with complexity of O(n):
lt = [(1,2,'x'), (2,3,'x'), (1,2,'z'), (2,20,'z')]
res = {}
for i in lt:
res.setdefault(i[2], []).append(i)
print(list(res.values()))
output:
>>>
[[(1, 2, 'x'), (2, 3, 'x')], [(1, 2, 'z'), (2, 20, 'z')]]
CodePudding user response:
nested list comprehension
if you dont know third_indices
a priori:
my_list = [(1,2,'x'), (2,3,'x'), (1,2,'z'), (2,20,'z')]
third_indices = set([ix[-1] for ix in my_list])
[[item for item in my_list if item[-1]==ix] for ix in third_indices]
CodePudding user response:
Similar to @eshirvana, but using defaultdict, which is very performant and common for this type of problem. I would make a defaultdict and save lists of tuples based the key determined by the last element. Then all your groups will be in the values()
from collections import defaultdict
l = [(1,2,'x'), (2,3,'x'), (1,2,'z'), (2,20,'z'), (3,4,'x')]
groups = defaultdict(list)
for t in l:
groups[t[-1]].append(t)
list(groups.values())
# [[(1, 2, 'x'), (2, 3, 'x'), (3, 4, 'x')], [(1, 2, 'z'), (2, 20, 'z')]]
CodePudding user response:
You can do something like this:
my_list = [(1,2,x), (2,3,x), (1,2,z), (2,20,z)]
list_x = [item for item in my_list if item[2] == x]
list_y = [item for item in my_list if item[2] == y]
list_z = [item for item in my_list if item[2] == z]
Edit: If x,y and z are not numbers then this should work:
my_list = [(1,2,'x'), (2,3,'x'), (1,2,'z'), (2,20,'z')]
list_x = [item for item in my_list if item[2] == 'x']
list_y = [item for item in my_list if item[2] == 'y']
list_z = [item for item in my_list if item[2] == 'z']
If you want them in the same list then do this
final_list = list((list_x,list_z))