How are tuples unpacked in for loops?
Asked Answered
T

8

89

I stumbled across the following code:

for i, a in enumerate(attributes):
   labels.append(Label(root, text = a, justify = LEFT).grid(sticky = W))
   e = Entry(root)
   e.grid(column=1, row=i)
   entries.append(e)
   entries[i].insert(INSERT,"text to insert")

I don't understand the i, a bit, and searching for information on for didn't yield any useful results. When I try and experiment with the code I get the error:

ValueError: need more than 1 value to unpack

Does anyone know what it does, or a more specific term associated with it that I can google to learn more?

Taunyataupe answered 3/6, 2012 at 4:24 Comment(0)
G
156

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.

Gruesome answered 3/6, 2012 at 4:27 Comment(0)
T
27

Enumerate basically gives you an index to work with in the for loop. So:

for i,a in enumerate([4, 5, 6, 7]):
    print(i, ": ", a)

Would print:

0: 4
1: 5
2: 6
3: 7
Thermostatics answered 3/6, 2012 at 4:29 Comment(0)
H
8

You can combine the for index,value approach with direct unpacking of tuples using ( ). This is useful where you want to set up several related values in your loop that can be expressed without an intermediate tuple variable or dictionary, e.g.

users = [
    ('alice', '[email protected]', 'dog'),
    ('bob', '[email protected]', 'cat'),
    ('fred', '[email protected]', 'parrot'),
]

for index, (name, addr, pet) in enumerate(users):
    print(index, name, addr, pet)

prints

0 alice [email protected] dog
1 bob [email protected] cat
2 fred [email protected] parrot
Huertas answered 12/4, 2021 at 15:38 Comment(1)
Thanks, this is just what I was looking for. Already knew how to use enumerate but wasn't aware of the for idx, (name, addr, pet) tuple unpacking method. Cheers!Photoelectrotype
C
6

Take this code as an example:

elements = ['a', 'b', 'c', 'd', 'e']
index = 0

for element in elements:
  print element, index
  index += 1

You loop over the list and store an index variable as well. enumerate() does the same thing, but more concisely:

elements = ['a', 'b', 'c', 'd', 'e']

for index, element in enumerate(elements):
  print element, index

The index, element notation is required because enumerate returns a tuple ((1, 'a'), (2, 'b'), ...) that is unpacked into two different variables.

Carousel answered 3/6, 2012 at 4:29 Comment(0)
D
6
[i for i in enumerate(['a','b','c'])]

Result:

[(0, 'a'), (1, 'b'), (2, 'c')]
Digger answered 3/6, 2012 at 7:11 Comment(2)
Hello, Is there a name for this feature that you did here? Google doesn't seem to be fruitful. [i for i in enumerate(['a','b','c'])]Ursulaursulette
This is called a list comprehensionPalmy
N
2

The enumerate function returns a generator object which, at each iteration, yields a tuple containing the index of the element (i), numbered starting from 0 by default, coupled with the element itself (a), and the for loop conveniently allows you to access both fields of those generated tuples and assign variable names to them.

Neuberger answered 3/6, 2012 at 4:28 Comment(0)
V
2

Short answer, unpacking tuples from a list in a for loop works. enumerate() creates a tuple using the current index and the entire current item, such as (0, ('bob', 3))

I created some test code to demonstrate this:

    list = [('bob', 3), ('alice', 0), ('john', 5), ('chris', 4), ('alex', 2)]

    print("Displaying Enumerated List")
    for name, num in enumerate(list):
        print("{0}: {1}".format(name, num))

    print("Display Normal Iteration though List")
    for name, num in list:
        print("{0}: {1}".format(name, num))

The simplicity of Tuple unpacking is probably one of my favourite things about Python :D

Visceral answered 13/2, 2019 at 12:6 Comment(0)
I
0
let's get it through with an example:
list = [chips, drinks, and, some, coding]
  i = 0
  while i < len(list):
               
           if i % 2 != 0:
                print(i)
                  i+=1
       output:[drinks,some]

    now using EMUNERATE fuction:(precise)
   list = [chips, drinks, and, coding]
for index,items in enumerate(list):
            
             print(index,":",items)
OUTPUT:   0:drinks
          1:chips
          2:drinks
          3:and
          4:coding

                          


                         
Inflexed answered 26/1, 2022 at 6:48 Comment(2)
Please format your answer properlyPizzeria
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Guiscard

© 2022 - 2024 — McMap. All rights reserved.