Definition of Iterables
In general, iterables in Python are objects that can be iterated over, i.e. elements inside can be taken out of it one at a time. Lists, tuples, dictionaries, sets, and range (but not limited to these) are all iterables. Furthermore, an iterator is a closely related object equipped with the necessary corresponding methods, particularly next to retrieve the next entry. The aforementioned lists, tuples, dictionaries, sets, and range are not iterators by themselves and require the function iter to wrap them. (However, iterators are always iterable.) We now demonstrate this below:
my_iter = iter(["parsley", "sage", "rosemary", "thyme"])print(next(my_list))print(next(my_list))print(next(my_list))print(next(my_list))print(next(my_list))
This produces
parsleysagerosemarythymeTraceback (most recent call last): File "c:\Users\user\Downloads\test.py", line 9, in <module> print(next(my_list)) ~~~~^^^^^^^^^StopIteration
The first four next calls take the elements one by one in order. And when all of them have been exhausted, it returns an error indicating this. It can be used in for loops just like other iterables:
my_iter = iter(["parsley", "sage", "rosemary", "thyme"])for flower in my_iter: print("Get me a", flower, "!")
resulting in
Get me a parsley !Get me a sage !Get me a rosemary !Get me a thyme !
Enumerate
The enumerate function can be applied to any iterable and returns an iterator that runs through the elements inside the original iterable, but also with an index that comes before each, and they are paired in tuples. Let’s try to expand the above example:
my_iter_enum = enumerate(my_iter)print(next(my_iter_enum))print(next(my_iter_enum))print(next(my_iter_enum))print(next(my_iter_enum))
This will give
(0, 'parsley')(1, 'sage')(2, 'rosemary')(3, 'thyme')
This can also be supplied to a for loop. Since now each entry generated by the new enumerate object is a tuple with two components, we may explicitly expand (unpack) them by using two dummy variables in the for loop as well:
for index, flower in enumerate(my_iter): print(f"Item {index+1}: {flower}.")
The dummy index/flower assumes the first/second component returned by enumerate, and outputs
Item 1: parsley.Item 2: sage.Item 3: rosemary.Item 4: thyme.
Zip
When there are multiple iterables to be processed in parallel within a for loop, the zip function will pack them component by component into an iterator. To illustrate, we can write
colors = ["red", "yellow", "green", "blue"]shapes = ["circle", "square", "triangle", "star"]for color, shape in zip(colors, shapes): print(f"Here is a {color} {shape}.")
which gives
Here is a red circle.Here is a yellow square.Here is a green triangle.Here is a blue star.
This is the most convenient when used along with a dictionary (see this tutorial), and let’s recall the keys and values method:
cities_latlon = {"Beijing": (39.9, 116.4), "London": (51.5, 0.1), "Los Angeles": (34.1, -118.2)}for city, latlon in zip(cities_latlon.keys(), cities_latlon.values()): print(f"{city} is located at {latlon}.")
This produces
Beijing is located at (39.9, 116.4).London is located at (51.5, 0.1).Los Angeles is located at (34.1, -118.2).
Note that zip can be applied to more than two iterables and the readers may try to play around that.
Exercise
Given
unit_types = ["mage", "warrior", "hunter", "mage"]lvs = [53, 48, 51, 44]
print the following outputs
Unit 1: Level 53 mageUnit 2: Level 48 warriorUnit 3: Level 51 hunterUnit 4: Level 44 mage
You will need to combine zip and enumerate, and there are multiple ways to do it. You can select the first/second item in a zipped object by the usual indexing [0], [1].
Suggested Solution
A possible way is via
for index, stat in enumerate(zip(unit_types, lvs)): print(f"Unit {index+1}: Level {stat[1]} {stat[0]}")
However, a better approach involves “unpacking”, which will be further discussed in a future post:
for index, (unit, lv) in enumerate(zip(unit_types, lvs)): print(f"Unit {index+1}: Level {lv} {unit}")







Leave a Reply