Python for index range

How to loop with indexes in Python

If you’re moving to Python from C or Java, you might be confused by Python’s for loops. Python doesn’t actually have for loops… at least not the same kind of for loop that C-based languages have. Python’s for loops are actually foreach loops.

In this article I’ll compare Python’s for loops to those of other languages and discuss the usual ways we solve common problems with for loops in Python.

For loops in other languages

Before we look at Python’s loops, let’s take a look at a for loop in JavaScript:

var colors = ["red", "green", "blue", "purple"]; for (var i = 0; i  colors.length; i++)   console.log(colors[i]); > 

This JavaScript loop looks nearly identical in C/C++ and Java.

  1. Set a counter variable i to 0
  2. Check if the counter is less than the array length
  3. Execute the code in the loop or exit the loop if the counter is too high
  4. Increment the counter variable by 1

Looping in Python

Now let’s talk about loops in Python. First we’ll look at two slightly more familiar looping methods and then we’ll look at the idiomatic way to loop in Python.

while

If we wanted to mimic the behavior of our traditional C-style for loop in Python, we could use a while loop:

colors = ["red", "green", "blue", "purple"] i = 0 while i  len(colors):  print(colors[i])  i += 1 

This involves the same 4 steps as the for loops in other languages (note that we’re setting, checking, and incrementing i ) but it’s not quite as compact.

This method of looping in Python is very uncommon.

range of length

I often see new Python programmers attempt to recreate traditional for loops in a slightly more creative fashion in Python:

colors = ["red", "green", "blue", "purple"] for i in range(len(colors)):  print(colors[i]) 

This first creates a range corresponding to the indexes in our list ( 0 to len(colors) — 1 ). We can loop over this range using Python’s for-in loop (really a foreach).

This provides us with the index of each item in our colors list, which is the same way that C-style for loops work. To get the actual color, we use colors[i] .

for-in: the usual way

Both the while loop and range-of-len methods rely on looping over indexes. But we don’t actually care about the indexes: we’re only using these indexes for the purpose of retrieving elements from our list.

Because we don’t actually care about the indexes in our loop, there is a much simpler method of looping we can use:

colors = ["red", "green", "blue", "purple"] for color in colors:  print(color) 

So instead of retrieving the item indexes and looking up each element, we can just loop over our list using a plain for-in loop.

The other two methods we discussed are sometimes referred to as anti-patterns because they are programming patterns which are widely considered unidiomatic.

What if we need indexes?

What if we actually need the indexes? For example, let’s say we’re printing out president names along with their numbers (based on list indexes).

range of length

We could use range(len(our_list)) and then lookup the index like before:

presidents = ["Washington", "Adams", "Jefferson", "Madison", "Monroe", "Adams", "Jackson"] for i in range(len(presidents)):  print("President <>: <>".format(i + 1, presidents[i])) 

But there’s a more idiomatic way to accomplish this task: use the enumerate function.

enumerate

Python’s built-in enumerate function allows us to loop over a list and retrieve both the index and the value of each item in the list:

presidents = ["Washington", "Adams", "Jefferson", "Madison", "Monroe", "Adams", "Jackson"] for num, name in enumerate(presidents, start=1):  print("President <>: <>".format(num, name)) 

The enumerate function gives us an iterable where each element is a tuple that contains the index of the item and the original item value.

This function is meant for solving the task of:

  1. Accessing each item in a list (or another iterable)
  2. Also getting the index of each item accessed

So whenever we need item indexes while looping, we should think of enumerate .

Note: the start=1 option to enumerate here is optional. If we didn’t specify this, we’d start counting at 0 by default.

What if we need to loop over multiple things?

Often when we use list indexes, it’s to look something up in another list.

enumerate

For example, here we’re looping over two lists at the same time using indexes to look up corresponding elements:

colors = ["red", "green", "blue", "purple"] ratios = [0.2, 0.3, 0.1, 0.4] for i, color in enumerate(colors):  ratio = ratios[i]  print("<>% <>".format(ratio * 100, color)) 

Note that we only need the index in this scenario because we’re using it to lookup elements at the same index in our second list. What we really want is to loop over two lists simultaneously: the indexes just provide a means to do that.

zip

We don’t actually care about the index when looping here. Our real goal is to loop over two lists at once. This need is common enough that there’s a special built-in function just for this.

Python’s zip function allows us to loop over multiple lists at the same time:

colors = ["red", "green", "blue", "purple"] ratios = [0.2, 0.3, 0.1, 0.4] for color, ratio in zip(colors, ratios):  print("<>% <>".format(ratio * 100, color)) 

The zip function takes multiple lists and returns an iterable that provides a tuple of the corresponding elements of each list as we loop over it.

Note that zip with different size lists will stop after the shortest list runs out of items. You may want to look into itertools.zip_longest if you need different behavior. Also note that zip in Python 2 returns a list but zip in Python 3 returns a lazy iterable. In Python 2, itertools.izip is equivalent to the newer Python 3 zip function.

Looping cheat sheet

Here’s a very short looping cheat sheet that might help you remember the preferred construct for each of these three looping scenarios.

Loop over a single list with a regular for-in:

Loop over multiple lists at the same time with zip :

for header, rows in zip(headers, columns):  print("<>: <>".format(header, ", ".join(rows))) 

Loop over a list while keeping track of indexes with enumerate :

for num, line in enumerate(lines):  print(": <>".format(num, line)) 

In Summary

If you find yourself tempted to use range(len(my_list)) or a loop counter, think about whether you can reframe your problem to allow usage of zip or enumerate (or a combination of the two).

In fact, if you find yourself reaching for enumerate , think about whether you actually need indexes at all. It’s quite rare to need indexes in Python.

  1. If you need to loop over multiple lists at the same time, use zip
  2. If you only need to loop over a single list just use a for-in loop
  3. If you need to loop over a list and you need item indexes, use enumerate

If you find yourself struggling to figure out the best way to loop, try using the cheat sheet above.

Practice makes perfect

You don’t learn by putting information in your head, you learn by attempting to retrieve information from your head. So you’ve just read an article on something new, but you haven’t learned yet.

Write some code that uses enumerate and zip later today and then quiz yourself tomorrow on the different ways of looping in Python. You have to practice these skills if you want to actually remember them.

If you’d like to get hands-on experience practicing Python every week, I have a Python skill-building service you should consider joining. If you sign up for Python Morsels I’ll give you a Python looping exercise that right now and then I’ll send you one new Python exercise every week after that.

Fill out the form above to sign up for Python Morsels, get some practice with the zip function, and start leveling-up your Python skills every week.

Posted by Trey Hunner Apr 25 th , 2016 9:00 am favorite, python

Источник

For loops

There are two ways to create loops in Python: with the for-loop and the while-loop.

When do I use for loops

for loops are used when you have a block of code which you want to repeat a fixed number of times. The for-loop is always used in combination with an iterable object, like a list or a range. The Python for statement iterates over the members of a sequence in order, executing the block each time. Contrast the for statement with the »while» loop, used when a condition needs to be checked each iteration or to repeat a block of code forever. For example:

For loop from 0 to 2, therefore running 3 times.

for x in range(0, 3): print("We're on time %d" % (x))

While loop from 1 to infinity, therefore running forever.

x = 1 while True: print("To infinity and beyond! We're getting close, on %d now!" % (x)) x += 1

When running the above example, you can stop the program by pressing ctrl+c at the same time. As you can see, these loop constructs serve different purposes. The for loop runs for a fixed amount of times, while the while loop runs until the loop condition changes. In this example, the condition is the boolean True which will never change, so it will run forever.

How do they work?

If you’ve done any programming before, you have undoubtedly come across a for loop or an equivalent to it. Many languages have conditions in the syntax of their for loop, such as a relational expression to determine if the loop is done, and an increment expression to determine the next loop value. In Python, this is controlled instead by generating the appropriate sequence. Basically, any object with an iterable method can be used in a for loop. Even strings, despite not having an iterable method — but we’ll not get on to that here. Having an iterable method basically means that the data can be presented in list form, where there are multiple values in an orderly fashion. You can define your own iterables by creating an object with next() and iter() methods. This means that you’ll rarely be dealing with raw numbers when it comes to for loops in Python — great for just about anyone!

Nested loops

When you have a block of code you want to run x number of times, then a block of code within that code which you want to run y number of times, you use what is known as a «nested loop». In Python, these are heavily used whenever someone has a list of lists — an iterable object within an iterable object.

for x in range(1, 11): for y in range(1, 11): print('%d * %d = %d' % (x, y, x*y))

Like the while loop, the for loop can be made to exit before the given object is finished. This is done using the break statement, which will immediately drop out of the loop and continue execution at the first statement after the block. You can also have an optional else clause, which will run should the for loop exit cleanly — that is, without breaking.

for x in range(3): if x == 1: break

Examples

for x in range(3): print(x) else: print('Final x = %d' % (x))
string = "Hello World" for x in string: print(x)
collection = ['hey', 5, 'd'] for x in collection: print(x)
list_of_lists = [ [1, 2, 3], [4, 5, 6], [7, 8, 9]] for list in list_of_lists: for x in list: print(x)

Creating your own iterable

class Iterable(object): def __init__(self,values): self.values = values self.location = 0 def __iter__(self): return self def next(self): if self.location == len(self.values): raise StopIteration value = self.values[self.location] self.location += 1 return value

Your own range generator using yield

def my_range(start, end, step): while start yield start start += step for x in my_range(1, 10, 0.5): print(x)

A note on `range`

The »range» function is seen so often in for statements that you might think range is part of the for syntax. It is not: it is a Python built-in function that returns a sequence following a specific pattern (most often sequential integers), which thus meets the requirement of providing a sequence for the for statement to iterate over. Since for can operate directly on sequences, there is often no need to count. This is a common beginner construct (if they are coming from another language with different loop syntax):

mylist = ['a', 'b', 'c', 'd'] for i in range(len(mylist)): # do something with mylist[i]

It can be replaced with this:

mylist = ['a', 'b', 'c', 'd'] for v in mylist: # do something with v

Consider for var in range(len(something)): to be a flag for possibly non-optimal Python coding.

More resources

ForLoop (last edited 2022-01-23 09:18:40 by eriky )

Источник

Читайте также:  Java аргументы для майнкрафт сервера
Оцените статью