How Are Tuples Unpacked in for Loops

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.

Unpacking a tuple in for loop

If you go step-by-step...

First, doing p = a, b will get you a tuple consisting of exactly 2 elements -- your lists:

>>> a = [0, 1, 2, 3]
>>> b = [4, 5, 6, 7]
>>> p = a, b
>>> print p
([0,1,2,3], [4, 5, 6, 7])

Then, when you do for i, k in p, Python will attempt to get the first item inside p then unpack it into i, k. So, then, the first iteration of your loop is basically doing something equivalent to this:

>>> temp = p[0]
>>> print temp
[0, 1, 2, 3]
>>> i, j = temp
Traceback (most recent call last):
File "<stdin>", line 1 in <module>
ValueError: too many values to unpack

This will fail, since what you're basically trying to do is i, k = [0, 1, 2, 3], and there are more elements in the list then there are variables.

You may want to use the zip function instead, which pairs up the numbers inside both lists.

For example:

>>> p = zip(a, b)
>>> print p
[(0, 4), (1, 5), (2, 6), (3, 7)]

That way, when we run your loop, the number of elements inside the first tuple matches the number of variables in your loop, so Python will not throw an error. That means that your output would be:

0 4
1 5
2 6
3 7

If that's not your desired output, you need to rethink the structure of your code.


Edit:

Based on your update, if you just want your output to be:

[0, 1, 2, 3]
[4, 5, 6, 7]

...then you don't actually need to use unpacking at all. The following loop would work just fine:

for i in p:
print i

i would be assigned to the first item inside p in the first iteration, then to the second item when the loop repeats.

Cannot unpack tuple object in FOR loop Python

You need to unpack it first.

m, n = ("example_string", True)

If the tuple contained iterables itself, then you could unpack it in the loop:

for m, n in (('x','y'), (x,y)):  # this works

How to unpack an object as it was a tuple in a for loop?

You are close, however, you need to yield the values in the __iter__ method, not the __next__ method:

class Test:
def __init__(self, arg):
self.arg1 = arg + 1
self.arg2 = arg + 2
self.arg3 = arg + 3
def __iter__(self):
yield from [self.arg1, self.arg2, self.arg3]

for a, b, c in [Test(0), Test(1), Test(2)]:
pass

yield self.arg1, self.arg2, self.arg3 will give a tuple result (1, 2, 3) which, when iterating over the list, requires additional unpacking i.e:

for [(a, b, c)] in [Test(0), Test(1), Test(2)]:
pass

Thus, in order to avoid the additional unpacking in the loop, you have to create a stream of generated values by looping over the attributes and yielding each, one at a time.

tuple unpacking in python using for loops?

You may want to be more specific about what you want to achieve.
Based on your "expected output", I assume you want the 1st element when the index is even and the 2nd element when the index is odd.

l=[(1,2),(3,4),(5,6)]
for idx, (x, y) in enumerate(l):
val = x if idx%2==0 else y
print(val)


Related Topics



Leave a reply



Submit