Looping tips
As a word of warning, it is generally not a good idea to alter the number of items in a list
while you are looping over that list, unless you really know what you are doing (and even
then we typically only add to the end). The sequence of elements that the loop goes
through will be hard to predict because the positional indices may not correspond to their
original values. Suppose you have a list of values and want to remove any that are less
than five. You could try the following:
values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for val in values:
if val < 5:
values.remove(val) # modify the loop list: bad idea
This does not work because the loop variable, val, gets confused about where it is in the
list when the list is modified inside the loop. In this case some of the values less than five
were skipped and not removed from the list:
print(values) # [1, 3, 5, 6, 7, 8, 9]
Instead you could duplicate the list, here using the list() function, and this now gives the
expected result:
values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for val in list(values):
if val < 5:
values.remove(val)
print(values) # [5, 6, 7, 8, 9]
With a duplicate, the list that is iterated over is now not modified inside the loop. In the
next example we show an alternative approach where the values are added to an initially
empty list. In general, constructing a new list in this way is more efficient than making a
copy and then removing internal items:
values = [0,1,2,3,4,5,6,7,8,9]
values2 = []
for val in values:
if val >= 5:
values2.append(val)
values = values2
The above is an example of filtering a collection according to a condition (and would
also work with a set or tuple). For this task we could also use a list comprehension, which
has no problems with modifying the list we are looping through and does the job on a
single line of code. This combines a for loop with a conditional if check, although the
latter is an optional part of the syntax.
values = [0,1,2,3,4,5,6,7,8,9]
values = [val for val in values if val >= 5]
If the code for the filter condition is complicated you may need to write the list
comprehension over more than one line. Though, if the filtering is done by a function then
it is easier to keep to a single line. You can also operate on the loop variable before adding
it to the filtered list. For example, here we import a mathematical function to calculate the
factorial of a number and then use that function to calculate the factorial value inside the
list comprehension:
from math import factorial
values = [0,1,2,3,4,5,6,7,8,9]
result = [factorial(val) for val in values if factorial(val) >= 700]
print(result) # [720, 5040, 40320, 362880]
This approach is where a list comprehension might not be such a good idea, because
although it is short, it calls the function (factorial() in this case twice; once for the
conditional test and once to construct the result list. Naturally this is best avoided if the
function is slow to calculate. Hence, for efficiency reasons you might want to stick with
the longer version:
values = [0,1,2,3,4,5,6,7,8,9]
result = []
for val in values:
fac = factorial(val)
if fac >= 700:
result.append(fac)
As mentioned earlier, you can loop over the keys of a dictionary. Normally you are
interested not just in the keys, but also in the value associated with the key in the
dictionary. However, if you have a dictionary and its keys, you can easily look up the
values. For example, suppose you have a dictionary, yearDict, for which the keys are the
names of months, and the value corresponding to each key is the number of days in that
month. If you want to calculate the total number of days from all the months it is a simple
matter of looping through all of the keys of the dictionary (the months), then using each
key in turn to get the value from the list, which is then added to the total.
yearDict = {'Jan':31,'Feb':28,'Mar':31,'Apr':30,
'May':31,'Jun':30,'Jul':31,'Aug':31,
'Sep':30,'Oct':31,'Nov':30,'Dec':31,}
total = 0
for month in yearDict: # loop through keys
total += yearDict[month] # lookup value
Do'stlaringiz bilan baham: |