How to make two lists out of two-elements tuples that are stored in a list of lists of tuples
Question:
I have a list which contains many lists and in those there 4 tuples.
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)],
[(110, 1), (34, 2), (12, 1), (55, 3)]]
I want them in two separate lists like:
my_list2 = [12,10,4,2,110,34,12,55]
my_list3 = [1,3,0,0,1,2,1,3]
my attempt was using the map
function for this.
my_list2 , my_list3 = map(list, zip(*my_list))
but this is giving me an error:
ValueError: too many values to unpack (expected 2)
Answers:
You can use list comprehension (5.1.3).
First number of tuple:
my_list2 = [tuple[0] for inner in my_list for tuple in inner]
Second number of tuple:
my_list3 = [tuple[1] for inner in my_list for tuple in inner]
A different, plain approach:
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)], [(110, 1), (34, 2), (12, 1), (55, 3)]]
first = []
second = []
for inner in my_list:
for each in inner:
first.append(each[0])
second.append(each[1])
print(first) # [12, 10, 4, 2, 110, 34, 12, 55]
print(second) # [1, 3, 0, 0, 1, 2, 1, 3]
How about this?
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)], [(110, 1), (34, 2), (12, 1), (55, 3)]]
flatten = lambda l: [item for my_list in l for item in my_list]
list1, list2 = zip(*flatten(my_list))
Your approach is quite close, but you need to flatten first:
from itertools import chain
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)], [(110, 1), (34, 2), (12, 1), (55, 3)]]
my_list2 , my_list3 = map(list,zip(*chain.from_iterable(my_list)))
my_list2
# [12, 10, 4, 2, 110, 34, 12, 55]
my_list3
# [1, 3, 0, 0, 1, 2, 1, 3]
Try it:
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)], [(110, 1), (34, 2), (12, 1), (55, 3)]]
my_list2, my_list3 = map(list, zip(*[j for i in my_list for j in i]))
print(my_list2)
# [12, 10, 4, 2, 110, 34, 12, 55]
print(my_list3)
# [1, 3, 0, 0, 1, 2, 1, 3]
Here is one way:
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)], [(110, 1), (34, 2), (12, 1), (55, 3)]]
my_list2 = [a for b in [[t[0] for t in my_list[i]] for i,n in enumerate(my_list)] for a in b]
my_list3 = [a for b in [[t[1] for t in my_list[i]] for i,n in enumerate(my_list)] for a in b]
print(my_list2)
print(my_list3)
Output:
[12, 10, 4, 2, 110, 34, 12, 55]
[1, 3, 0, 0, 1, 2, 1, 3]
How about a minimalist solution:
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)], [(110, 1), (34, 2), (12, 1), (55, 3)]]
my_list2, my_list3 = zip(*sum(my_list, []))
print(my_list2)
print(my_list3)
OUTPUT
> python3 test.py
(12, 10, 4, 2, 110, 34, 12, 55)
(1, 3, 0, 0, 1, 2, 1, 3)
>
convert the list of tuples to an 2d array then slice the array
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)],
[(110, 1), (34, 2), (12, 1), (55, 3)]]
a = np.array(my_list)
my_list2= np.array([])
my_list3= np.array([])
my_list2=np.append(my_list2,[item[:,0] for item in a])
my_list3=np.append(my_list3,[item[:,1] for item in a])
print(my_list2)
print(my_list3)
output:
[ 12. 10. 4. 2. 110. 34. 12. 55.]
[1. 3. 0. 0. 1. 2. 1. 3.]
I have a list which contains many lists and in those there 4 tuples.
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)],
[(110, 1), (34, 2), (12, 1), (55, 3)]]
I want them in two separate lists like:
my_list2 = [12,10,4,2,110,34,12,55]
my_list3 = [1,3,0,0,1,2,1,3]
my attempt was using the map
function for this.
my_list2 , my_list3 = map(list, zip(*my_list))
but this is giving me an error:
ValueError: too many values to unpack (expected 2)
You can use list comprehension (5.1.3).
First number of tuple:
my_list2 = [tuple[0] for inner in my_list for tuple in inner]
Second number of tuple:
my_list3 = [tuple[1] for inner in my_list for tuple in inner]
A different, plain approach:
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)], [(110, 1), (34, 2), (12, 1), (55, 3)]]
first = []
second = []
for inner in my_list:
for each in inner:
first.append(each[0])
second.append(each[1])
print(first) # [12, 10, 4, 2, 110, 34, 12, 55]
print(second) # [1, 3, 0, 0, 1, 2, 1, 3]
How about this?
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)], [(110, 1), (34, 2), (12, 1), (55, 3)]]
flatten = lambda l: [item for my_list in l for item in my_list]
list1, list2 = zip(*flatten(my_list))
Your approach is quite close, but you need to flatten first:
from itertools import chain
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)], [(110, 1), (34, 2), (12, 1), (55, 3)]]
my_list2 , my_list3 = map(list,zip(*chain.from_iterable(my_list)))
my_list2
# [12, 10, 4, 2, 110, 34, 12, 55]
my_list3
# [1, 3, 0, 0, 1, 2, 1, 3]
Try it:
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)], [(110, 1), (34, 2), (12, 1), (55, 3)]]
my_list2, my_list3 = map(list, zip(*[j for i in my_list for j in i]))
print(my_list2)
# [12, 10, 4, 2, 110, 34, 12, 55]
print(my_list3)
# [1, 3, 0, 0, 1, 2, 1, 3]
Here is one way:
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)], [(110, 1), (34, 2), (12, 1), (55, 3)]]
my_list2 = [a for b in [[t[0] for t in my_list[i]] for i,n in enumerate(my_list)] for a in b]
my_list3 = [a for b in [[t[1] for t in my_list[i]] for i,n in enumerate(my_list)] for a in b]
print(my_list2)
print(my_list3)
Output:
[12, 10, 4, 2, 110, 34, 12, 55]
[1, 3, 0, 0, 1, 2, 1, 3]
How about a minimalist solution:
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)], [(110, 1), (34, 2), (12, 1), (55, 3)]]
my_list2, my_list3 = zip(*sum(my_list, []))
print(my_list2)
print(my_list3)
OUTPUT
> python3 test.py
(12, 10, 4, 2, 110, 34, 12, 55)
(1, 3, 0, 0, 1, 2, 1, 3)
>
convert the list of tuples to an 2d array then slice the array
my_list = [[(12, 1), (10, 3), (4, 0), (2, 0)],
[(110, 1), (34, 2), (12, 1), (55, 3)]]
a = np.array(my_list)
my_list2= np.array([])
my_list3= np.array([])
my_list2=np.append(my_list2,[item[:,0] for item in a])
my_list3=np.append(my_list3,[item[:,1] for item in a])
print(my_list2)
print(my_list3)
output:
[ 12. 10. 4. 2. 110. 34. 12. 55.]
[1. 3. 0. 0. 1. 2. 1. 3.]