How to unzip a list of tuples into individual lists?
Use zip(*list)
:
>>> l = [(1,2), (3,4), (8,9)]
>>> list(zip(*l))
[(1, 3, 8), (2, 4, 9)]
The zip()
function pairs up the elements from all inputs, starting with the first values, then the second, etc. By using *l
you apply all tuples in l
as separate arguments to the zip()
function, so zip()
pairs up 1
with 3
with 8
first, then 2
with 4
and 9
. Those happen to correspond nicely with the columns, or the transposition of l
.
zip()
produces tuples; if you must have mutable list objects, just map()
the tuples to lists or use a list comprehension to produce a list of lists:
map(list, zip(*l)) # keep it a generator
[list(t) for t in zip(*l)] # consume the zip generator into a list of lists
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.
unzip list of tuples into numpy arrays
Your list of tuples can be converted into a 2-d numpy array by calling np.array
. This can then be transposed and then unpacked along the first dimension using tuple assignment:
b, c = np.array(a).T
Here this gives:
>>> import numpy as np
>>> a = [(1,2), (3,4)]
>>> b, c = np.array(a).T # or: np.array(a).transpose()
>>> b
array([1, 3])
>>> c
array([2, 4])
Caveat: you will have a temporary array with the same number of elements as a
, so it might be less memory-efficient than your original solution, particularly if you are unpacking into a larger number of 1d arrays.
Transpose/Unzip Function (inverse of zip)?
zip
is its own inverse! Provided you use the special * operator.
>>> zip(*[('a', 1), ('b', 2), ('c', 3), ('d', 4)])
[('a', 'b', 'c', 'd'), (1, 2, 3, 4)]
The way this works is by calling zip
with the arguments:
zip(('a', 1), ('b', 2), ('c', 3), ('d', 4))
… except the arguments are passed to zip
directly (after being converted to a tuple), so there's no need to worry about the number of arguments getting too big.
python3 unzipping a list of tuples
Python 2:
Python 2.7.6 (default, Apr 9 2014, 11:48:52)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> di={'word1':22, 'word2':45, 'word3':66}
>>> zip(*sorted(di.items(), key=itemgetter(1), reverse=True))
[('word3', 'word2', 'word1'), (66, 45, 22)]
>>> k,v=zip(*sorted(di.items(), key=itemgetter(1), reverse=True))
>>> k
('word3', 'word2', 'word1')
>>> v
(66, 45, 22)
Python 3:
Python 3.4.1 (default, May 19 2014, 13:10:29)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> di={'word1':22, 'word2':45, 'word3':66}
>>> k,v=zip(*sorted(di.items(), key=itemgetter(1), reverse=True))
>>> k
('word3', 'word2', 'word1')
>>> v
(66, 45, 22)
It is exactly the same for both Python 2 and Python 3
If you want lists vs tuples (both Python 3 and Python 2):
>>> k,v=map(list, zip(*sorted(di.items(), key=itemgetter(1), reverse=True)))
>>> k
['word3', 'word2', 'word1']
>>> v
[66, 45, 22]
How to unpack single-item tuples in a list of lists
You need nested comprehensions (with either a two layer loop in the inner comprehension, or use chain.from_iterable
for flattening). Example with two layer loop (avoids need for imports), see the linked question for other ways to flatten the inner list
of tuple
s:
>>> listolists = [[('1st',), ('2nd',), ('5th',)], [('1st',)]]
>>> [[x for tup in lst for x in tup] for lst in listolists]
[['1st', '2nd', '5th'], ['1st']]
Note that in this specific case of single element tuple
s, you can avoid the more complicated flattening with just:
>>> [[x for x, in lst] for lst in listolists]
per the safest way of getting the only element from a single-element sequence in Python.
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.
How to convert list of tuples to multiple lists?
The built-in function zip()
will almost do what you want:
>>> list(zip(*[(1, 2), (3, 4), (5, 6)]))
[(1, 3, 5), (2, 4, 6)]
The only difference is that you get tuples instead of lists. You can convert them to lists using
list(map(list, zip(*[(1, 2), (3, 4), (5, 6)])))
Related Topics
How to Set the Aspect Ratio in Matplotlib
Python & MySQL: Unicode and Encoding
How to Compare String and Integer in Python
Doing Something Before Program Exit
Python Webbrowser.Open() to Open Chrome Browser
Efficiently Return the Index of the First Value Satisfying Condition in Array
Libxml Install Error Using Pip
Reading a Text File and Splitting It into Single Words in Python
Python Os.Path.Join on Windows
Run Command and Get Its Stdout, Stderr Separately in Near Real Time Like in a Terminal
Python JSON Parser Allow Duplicate Keys