The Art of Writing Loops in Python





The loop for



is the most basic control flow tool in most programming languages. For example, a simple for



C loop looks like this:



int i;
for (i=0;i<N;i++)
{
  //do something
}
      
      





There is no nicer way to write for



a C loop . In complex cases, you usually have to write ugly nested loops or set a lot of auxiliary variables (like i



in the code above).



Fortunately, things are more convenient in Python. There are many tricks in this language to write more graceful loops that make our life easier. In Python, it is quite possible to avoid nested loops and auxiliary variables, and we can even customize the loop ourselves for



.



This article will walk you through the most useful Python looping tricks. I hope it helps you experience the beauty of this language.



Get values ​​and indices at the same time



A common example of using a loop for



is getting indices and values ​​from a list. When I started learning Python, I wrote my code this way:



for i in range(len(my_list)):
    print(i, my_list[i])
      
      





It worked, of course. But this is not a Python-style solution. A few months later, I learned the standard Python-style implementation:



for i, v in enumerate(my_list):
    print(i, v)
      
      





As we can see, the built-in function enumerate



makes our life easier.



How to avoid nested loops with the Product function



Nested loops are a real headache. They can reduce the readability of your code and make it harder to understand. For example, interrupting nested loops is usually not easy to implement. We need to know where the innermost loop was interrupted, the second-highest inner loop, and so on.



Fortunately, Python has an awesome product



built-in function itertools



. We can use it to avoid writing many nested loops.



Let's see how useful it is with a simple example:



list_a = [1, 2020, 70]
list_b = [2, 4, 7, 2000]
list_c = [3, 70, 7]

for a in list_a:
    for b in list_b:
        for c in list_c:
            if a + b + c == 2077:
                print(a, b, c)
# 70 2000 7
      
      





As we can see, we need three nested loops to get three numbers from three lists, the sum of which is 2077. The code is not very pretty.



Now let's try using a function product



.



from itertools import product

list_a = [1, 2020, 70]
list_b = [2, 4, 7, 2000]
list_c = [3, 70, 7]

for a, b, c in product(list_a, list_b, list_c):
    if a + b + c == 2077:
        print(a, b, c)
# 70 2000 7
      
      





As we can see, thanks to the use of the function product



, just one cycle is enough.



Since the function product



generates a direct product of the input iterable data, it allows us to avoid nested loops in many cases.



Using the Itertools Module to Write Nice Loops



In fact, a function product



is just the tip of the iceberg. If you learn the built-in Python module itertools



, a whole new world opens up before you. This toolkit contains many useful methods to cover our looping needs. A complete list of them can be found in the official documentation . Let's take a look at some examples.



How to create an endless loop



There are at least three ways to create an infinite loop:



1. Using a function count



:



natural_num = itertools.count(1)
for n in natural_num:
    print(n)
# 1,2,3,...
      
      





2. Function cycle



:



many_yang = itertools.cycle('Yang')
for y in many_yang:
    print(y)
# 'Y','a','n','g','Y','a','n','g',...
      
      





3. Through the function repeat



:



many_yang = itertools.repeat('Yang')
for y in many_yang:
    print(y)
# 'Yang','Yang',...
      
      





Combining several iterators into one



The function chain()



allows you to combine multiple iterators into one.



from itertools import chain

list_a = [1, 22]
list_b = [7, 20]
list_c = [3, 70]

for i in chain(list_a, list_b, list_c):
    print(i)
# 1,22,7,20,3,70
      
      





Select adjacent duplicate elements



The function is groupby



used to select adjacent duplicate elements in an iterator and join them.



from itertools import groupby

for key, group in groupby('YAaANNGGG'):
    print(key, list(group))
# Y ['Y']
# A ['A']
# a ['a']
# A ['A']
# N ['N', 'N']
# G ['G', 'G', 'G']
      
      





As shown above, adjacent like symbols are connected together. Moreover, we can tell the function groupby



how to determine the identity of two elements:



from itertools import groupby

for key, group in groupby('YAaANNGGG', lambda x: x.upper()):
    print(key, list(group))
# Y ['Y']
# A ['A', 'a', 'A']
# N ['N', 'N']
# G ['G', 'G', 'G']
      
      





Customizing the cycle



After reviewing the examples above, let's think about why for



Python loops are so flexible and graceful. As far as I understand, this is due to the fact that we can apply for



functions in the loop iterator . In all the examples above, the iterator just uses special functions. All tricks have the same pattern:



for x in function(iterator)
      
      





The built-in module itself itertools



only implements the most common functions for us. If we forget a function or can't find the one we need, we can just write it ourselves. To be more precise, these functions are generators . That is why we can generate infinite loops with them.



Basically, we can customize the loop for



as we would with a custom generator.



Let's take a look at a simple example:



def even_only(num):
    for i in num:
        if i % 2 == 0:
            yield i


my_list = [1, 9, 3, 4, 2, 5]
for n in even_only(my_list):
    print(n)
# 4
# 2
      
      





As you can see from the above example, we have defined a generator called even_only



. If we use this generator in a for loop, iteration will only occur for even numbers from the list.



Of course, this example is for explanation purposes only. There are other ways to do the same thing, such as using the List View .



my_list = [1, 9, 3, 4, 2, 5]
for n in (i for i in my_list if not i % 2):
    print(n)
# 4
# 2
      
      





Output



The task of creating loops in Python can be solved very flexibly and gracefully. To write convenient and simple loops, we can use built-in tools or even define generators ourselves.






Advertising



Reliable server for rent , create your own configuration in a couple of clicks and start working in a minute. Everything will work smoothly and with a very high uptime!



Join our Telegram chat .






All Articles