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
How to Do Exponentiation in Python
Cannot Install Lxml on MAC Os X 10.9
Find First Element in a Sequence That Matches a Predicate
Increment a Python Floating Point Value by the Smallest Possible Amount
How to Install 2 Anacondas (Python 2 and 3) on MAC Os
Add X and Y Labels to a Pandas Plot
How Does Perspective Transformation Work in Pil
Python Argparse Mutual Exclusive Group
Can't Get Argparse to Read Quoted String with Dashes in It
Cannot Concatenate 'Str' and 'Float' Objects
Google Colab: How to Read Data from My Google Drive
Spark Dataframe Distinguish Columns with Duplicated Name
What Does a for Loop Within a List Do in Python
Want to Find Contours -> Valueerror: Not Enough Values to Unpack (Expected 3, Got 2), This Appears