What is the pythonic way to unpack tuples?
Generally, you can use the func(*tuple)
syntax. You can even pass a part of the tuple, which seems like what you're trying to do here:
t = (2010, 10, 2, 11, 4, 0, 2, 41, 0)
dt = datetime.datetime(*t[0:7])
This is called unpacking a tuple, and can be used for other iterables (such as lists) too. Here's another example (from the Python tutorial):
>>> range(3, 6) # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args) # call with arguments unpacked from a list
[3, 4, 5]
Unpack tuples inside a tuple
If you're looking to flatten a general tuple of tuples, you could:
- use a list/generator comprehension
flattened_tup = tuple(j for i in tup for j in i)
- use itertools
import itertools
flattened_tup = tuple(itertools.chain.from_iterable(tup))
Unpack python tuple with [ ]'s
No, those are all exactly equivalent. One way to look at this empirically is to use the dis
dissasembler:
>>> import dis
>>> dis.dis("a, b, c = (1, 2, 3)")
1 0 LOAD_CONST 0 ((1, 2, 3))
2 UNPACK_SEQUENCE 3
4 STORE_NAME 0 (a)
6 STORE_NAME 1 (b)
8 STORE_NAME 2 (c)
10 LOAD_CONST 1 (None)
12 RETURN_VALUE
>>> dis.dis("(a, b, c) = (1, 2, 3)")
1 0 LOAD_CONST 0 ((1, 2, 3))
2 UNPACK_SEQUENCE 3
4 STORE_NAME 0 (a)
6 STORE_NAME 1 (b)
8 STORE_NAME 2 (c)
10 LOAD_CONST 1 (None)
12 RETURN_VALUE
>>> dis.dis("[a, b, c] = (1, 2, 3)")
1 0 LOAD_CONST 0 ((1, 2, 3))
2 UNPACK_SEQUENCE 3
4 STORE_NAME 0 (a)
6 STORE_NAME 1 (b)
8 STORE_NAME 2 (c)
10 LOAD_CONST 1 (None)
12 RETURN_VALUE
>>>
From the formal language specification, this is detailed here. This is part of the "target list", A relevant quote:
Assignment of an object to a target list, optionally enclosed in
parentheses or square brackets, is recursively defined as
follows....
Python Tuple Unpacking
Use zip
, then unpack:
nums_and_words = [(1, 'one'), (2, 'two'), (3, 'three')]
nums, words = zip(*nums_and_words)
Actually, this "unpacks" twice: First, when you pass the list of lists to zip
with *
, then when you distribute the result to the two variables.
You can think of zip(*list_of_lists)
as 'transposing' the argument:
zip(*[(1, 'one'), (2, 'two'), (3, 'three')])
== zip( (1, 'one'), (2, 'two'), (3, 'three') )
== [(1, 2, 3), ('one', 'two', 'three')]
Note that this will give you tuples; if you really need lists, you'd have to map
the result:
nums, words = map(list, zip(*nums_and_words))
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.
Clarifications on Python tuple unpacking
The catch is that the brackets of a parameter list always enclose a tuple.
They are brackets you could not omit. So they are not mixed up with operator-priority-brackets
By the way, fun fact:
write (NOTE THE COMMA AFTER THE x)
*x, = (1,2,3,4,5)
Then it works, just like you would neet to add a comma in a bracket to make it a tuple.
like (1) is no tuple, but (1,) is
How to unpack a tuple of lists
You can use the indexing of your tuple and then the lists to access the inner-most elements. For example, to get at the string 'a'
, you could call:
myTuple[0][0]
If you wanted to iterate over all the elements in the lists, you could use the chain
method form itertools
. For example:
from itertools import chain
for i in chain(*myTuple):
print(i)
Unpacking list of tuples
Let's look at what you have:
testcases = [([1, 1, 1], 2, 2)]
This is a list. Of size one. So testcases[0]
is the only element there is.
So this code:
for a, b, c in testcases:
pass
is a loop of length one. So each time through the loop (that is just the once), you get the element: ([1, 1, 1], 2, 2)
which is a tuple
. Of size three.
So unpacking that: a,b,c = testcases[0]
gives:
a == [1, 1, 1]
b == 2
c == 2
which is what you see printed.
How to unpack a tuple when indexing?
The problem with:
a[:, :, np.triu_indices(14)]
is that you are using as argument for []
a tuple of mixed types slice
and tuple
(tuple(slice, slice, tuple(np.ndarray, np.ndarray))
) and not a single tuple
(eventually with advanced indexing), e.g. tuple(slice, slice, np.ndarray, np.ndarray)
.
This is causing your troubles. I would not go into the details of what is happening in your case.
Changing that line to:
a[(slice(None),) * 2 + np.triu_indices(14)]
will fix your issues:
a[(slice(None),) * 2 + np.triu_indices(14)].shape
# (100, 50, 105)
Note that there are a couple of ways for rewriting:
(slice(None),) * 2 + np.triu_indices(14)
another way may be:
(slice(None), slice(None), *np.triu_indices(14))
Also, if you want to use the ...
syntax, you need to know that ...
is syntactic sugar for Ellipsis
, so that:
(Ellipsis,) + np.triu_indices(14)
or:
(Ellipsis, *np.triu_indices(14))
would work correctly:
a[(Ellipsis,) + np.triu_indices(14)].shape
# (100, 50, 105)
a[(Ellipsis, *np.triu_indices(14))].shape
# (100, 50, 105)
How are tuples unpacked in for loops?
You could google "tuple unpacking". This can be used in various places in Python. The simplest is in assignment:
>>> x = (1,2)
>>> a, b = x
>>> a
1
>>> b
2
In a for-loop it works similarly. If each element of the iterable is a tuple
, then you can specify two variables, and each element in the loop will be unpacked to the two.
>>> x = [(1,2), (3,4), (5,6)]
>>> for item in x:
... print "A tuple", item
A tuple (1, 2)
A tuple (3, 4)
A tuple (5, 6)
>>> for a, b in x:
... print "First", a, "then", b
First 1 then 2
First 3 then 4
First 5 then 6
The enumerate
function creates an iterable of tuples, so it can be used this way.
Related Topics
How to Efficiently Calculate a Running Standard Deviation
How to Perform HTML Decoding/Encoding Using Python/Django
Convert Image from Pil to Opencv Format
Calculating Arithmetic Mean (One Type of Average) in Python
Failed to Get Convolution Algorithm. This Is Probably Because Cudnn Failed to Initialize,
How to Capture Output of Python's Interpreter and Show in a Text Widget
Class That Acts as Mapping for **Unpacking
Schedule Python Script - Windows 7
Right Way to Reverse a Pandas Dataframe
Python: Syntaxerror: Eol While Scanning String Literal
Is It Feasible to Compile Python to MAChine Code
How to Append Data to a JSON File
Override Python's 'In' Operator
Fastest Way to Grow a Numpy Numeric Array
Extract Elements of List at Odd Positions
How Does This Input Work with the Python 'Any' Function