Iterables and iterators

INPUT · Slides

Getting the position and the item together

01 / 06

You were counting by hand

You want to list things off as "number 0, number 1". With the tools you have had so far there was only one way to write it.

Set up a variable to count and add one at the end of each turn. It works, but forget the adding and it goes quietly wrong.

fruits = ["apple", "orange"]number = 0for fruit in fruits:    print(number, fruit)    number += 1

Result

0 apple
1 orange

02 / 06

enumerate does the counting

One line does the lot: enumerate, which means to number things off.

Write for i, fruit in enumerate(fruits): and i holds the position, fruit holds the item. The numbering starts at 0 and climbs on its own.

Taking two names separated by a comma is the shape you met with items() on a dictionary. What is being handed over is a tuple.

fruits = ["apple", "orange"]for i, fruit in enumerate(fruits):    print(i, fruit)

Result

0 apple
1 orange

03 / 06

Inside it is a row of pairs

Like range, what enumerate gives back is a "make the next one when asked" helper. Show it as it is and you see nothing useful.

print(enumerate(fruits))<enumerate object at 0x1234abcd>

To see inside, put it through list. Out come the tuples, each pairing a number with an item.

fruits = ["apple", "orange"]print(list(enumerate(fruits)))

Result

[(0, 'apple'), (1, 'orange')]

04 / 06

start changes where the counting begins

Numbers you show to people want to begin at 1. For that, pass start=1 — the keyword argument from chapter 3.

Write enumerate(fruits, start=1) and the numbering runs 1, 2, 3 and on. There is no need to write i + 1 anywhere.

fruits = ["apple", "orange"]for i, fruit in enumerate(fruits, start=1):    print(f"number {i} is {fruit}")

Result

number 1 is apple
number 2 is orange

05 / 06

Where beginner code shows most

enumerate is one of the tools that most changes how code looks between a beginner and somebody experienced.

People who write Python see a hand-incremented counter and think, straight away, that you have not met enumerate. That is how ordinary it has become.

There is one thing to remember. When you want the position, reach for enumerate. That alone makes what you write look a great deal more like Python.

names = ["Yui", "Sou", "Aoi"]for i, name in enumerate(names, start=1):    print(f"no.{i} {name}")

Result

no.1 Yui
no.2 Sou
no.3 Aoi

06 / 06

Only when you need the number

That said, do not add it when you are not going to use the number. Code that takes an i and never touches it leaves the reader wondering what the number was for.

Position needed, enumerate; contents only, a plain for. Take only what you are going to use.

Next lesson is zip, which lines two rows up side by side and walks them together.

fruits = ["apple", "orange", "grape"]for i, fruit in enumerate(fruits):    if i % 2 == 0:        print(fruit)

Result

apple
grape