Unpacking a List/Tuple of Pairs into Two Lists/Tuples

Unpacking a list / tuple of pairs into two lists / tuples

>>> source_list = [('1','a'),('2','b'),('3','c'),('4','d')]
>>> list1, list2 = zip(*source_list)
>>> list1
('1', '2', '3', '4')
>>> list2
('a', 'b', 'c', 'd')

Edit: Note that zip(*iterable) is its own inverse:

>>> list(source_list) == zip(*zip(*source_list))
True

When unpacking into two lists, this becomes:

>>> list1, list2 = zip(*source_list)
>>> list(source_list) == zip(list1, list2)
True

Addition suggested by rocksportrocker.

How to split a list of 2-tuples into two lists?

a,b = zip(*y)

is all you need ...

or if you need them as lists and not tuples

a,b = map(list,zip(*y))

Creating two lists out of tuple with occasional double value for one list

Heres a quick and easy way to do it:

wordlist = [("mother", ["Mutter"]), ("and", ["und"]), ("father", ["Vater"]), ("I", ["ich", "mich"]),("not", ["nicht"]), ("at", ["dort", "da"]), ("home", ["Haus", "Zuhause"]), ("now", ["jetzt"])]

english = []
german = []

for pair in wordlist:
english.append(pair[0])
for item in pair[1]: german.append(item)

print(english)
print(german)

How to merge lists into a list of tuples?

In Python 2:

>>> list_a = [1, 2, 3, 4]
>>> list_b = [5, 6, 7, 8]
>>> zip(list_a, list_b)
[(1, 5), (2, 6), (3, 7), (4, 8)]

In Python 3:

>>> list_a = [1, 2, 3, 4]
>>> list_b = [5, 6, 7, 8]
>>> list(zip(list_a, list_b))
[(1, 5), (2, 6), (3, 7), (4, 8)]

How do I extract two lists from a tuple containing two lists before I zip them? (using OCaml)

You can use pattern matching to get the components of a tuple. For example, this function takes a tuple of two ints and returns their sum:

let add_uncurried tuple =
let (a, b) = tuple in a + b

To put it another way, you can write let (a, b) = tuple in ... to get the components of the tuple under the names a and b.

How Python 3 zip list/tuple unpacking works under the hood?

Eureka!

While I was trying to write my question clearly, I stumbled upon this answer Why does x,y = zip(*zip(a,b)) work in Python?, which gave me a hint that I still did not get before trying it in a REPL. The key is unpacking the result of zip:

print(*zip(l1,l2))
# Output: (1, 'a') (2, 'b') (3, 'c')

We get 3 tuples of 2 elements, which are treated like 3 lists of 2 elements passed as arguments to zip:

l1 = [ 1 , 2 ]
l2 = ['a','b']
l3 = ['+','-']

print(list(zip(l1,l2,l3)))
# Output: [(1, 'a', '+'), (2, 'b', '-')]

※ Note that if you use 3 lists of 4 elements, zip will output 4 lists of 3 elements

l1 = [ 1 , 2 , 3 , 4 ]
l2 = ['a','b','c','d']
l3 = ['+','-','*','/']

print(list(zip(l1,l2,l3)))
# Output: [(1, 'a', '+'), (2, 'b', '-'), (3, 'c', '*'), (4, 'd', '/')]

matrix rotation

I now think of it as rotating values in a matrix 90° to make rows into columns and columns into rows.

It is like rotating a matrix by providing the rows as arguments instead of the matrix itself.

multiple variable assignment and tuple/list unpacking

The last piece of the puzzle is to unpack the result and assign each tuple in its own variable using multiple assignment!

l1 = [1,2,3]
l2 = ['a','b','c']
l3,l4= zip(*zip(l1,l2))

print('l3= ',l3)
print('l4= ', l4)
# Output: l3= (1, 2, 3)
# l4= ('a', 'b', 'c')

Epilogue

I decided to keep writing this Q&A to learn by explaining what I had discovered by experimenting, after not immediately getting the meaning of the answer I found while writing.

I also hope that my analogy with matrix rotation will help someone else get it faster in the future.

python tuples: unpacking into a list using *args

You can use the list.extend method instead:

def add_grades(*args):
grades.extend(args):
return grades

What's an elegant way to extract a series of entries in a list of tuples into sublists?

You can use tuple() function to transform lists into tuples, so you will be able to append all of the tuples inside listOfTuples variable into the output that you need:

TRUE = 1
lot = [('selectable', 'frequency'), ('color', 'green'), ('item', '10 Hz'),
('value', 10), ('align', 'left'), ('hidden', TRUE), ('item', '20 Hz'),
('value', 20), ('align', 'right'), ('item', '50 Hz'), ('value', 50),
('item', '100 Hz'), ('value', 100), ('textColor', 0xFF0000)]

l = [[]]
for i in lot:
if i[0]=='item':
l[-1] = tuple(l[-1])
l.append([])
l[-1].append(i)
print(l[1:])

Output:

[(('item', '10 Hz'), ('value', 10), ('align', 'left'), ('hidden', 1)), (('item', '20 Hz'), ('value', 20), ('align', 'right')), (('item', '50 Hz'), ('value', 50)), [('item', '100 Hz'), ('value', 100), ('textColor', 16711680)]]

The only disadvantage of this method is that you need to remove the first element of the output list of tuples, so it may doesn't work in certain situations.



Related Topics



Leave a reply



Submit