86

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?

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
Talisin
  • 2,370
  • 3
  • 18
  • 17

8 Answers8

153

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.

Alex Waygood
  • 6,304
  • 3
  • 24
  • 46
BrenBarn
  • 242,874
  • 37
  • 412
  • 384
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
nathancahill
  • 10,452
  • 9
  • 51
  • 91
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.

Blender
  • 289,723
  • 53
  • 439
  • 496
6
[i for i in enumerate(['a','b','c'])]

Result:

[(0, 'a'), (1, 'b'), (2, 'c')]
sth
  • 222,467
  • 53
  • 283
  • 367
whi
  • 2,685
  • 6
  • 33
  • 40
  • 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'])]` – Zaid Khan Dec 07 '18 at 14:06
  • 1
    This is called a [list comprehension](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions) – jlhasson Sep 25 '19 at 22:16
5

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', 'alice@example.com', 'dog'),
    ('bob', 'bob@example.com', 'cat'),
    ('fred', 'fred@example.com', 'parrot'),
]

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

prints

0 alice alice@example.com dog
1 bob bob@example.com cat
2 fred fred@example.com parrot
tuck1s
  • 1,002
  • 9
  • 28
  • 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! – mildmelon Jun 07 '21 at 21:28
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.

Greg E.
  • 2,722
  • 1
  • 16
  • 22
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

lorkaan
  • 141
  • 7
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

                          


                         
  • 1
    Please format your answer properly – Tobias Wilfert Jan 26 '22 at 15:58
  • 1
    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](/help/how-to-answer). – Community Jan 26 '22 at 15:58