The python idea of the for cycle

  • 2020-06-07 04:43:47
  • OfStack

Why challenge yourself not to write for loop in your code? This forces you to use advanced, idiomatic grammar or libraries. Using python as an example, this article introduces a lot of syntax that you've seen in other people's code but rarely use yourself.

This is a challenge. I want you to avoid writing for loops under any circumstances. Similarly, I want you to find a scenario that would be too difficult to write in any other way than using the for loop. Please share your findings. I'd love to hear about them

It's been a while since I started exploring the awesome features of the Python language. At first, this was just a challenge for me to practice using more language features instead of what I learned from other programming languages. But things are getting more interesting! Not only is the code shorter and cleaner, but it also looks more structured and organized, and I'll cover more of these benefits in this article.

First, let's take a step back and look at the intuition behind writing an for loop:

1. Iterate through 1 sequence to extract 1 bit of information

2. Generate additional sequences from the current sequence

3. for loops have become my second nature since I'm a programmer

Fortunately, Python already has great tools to help you achieve these goals! All you have to do is change your mind and look at things from a different perspective.

What do you get if you don't write for loops everywhere

1. Fewer lines of code

2. Better code reading

3. Use indentation only to manage code text

Let's see the code skeleton below:

Take a look at the architecture of this code:


# 1
with ...:
  for ...:
    if ...:
      try:
      except:
    else:

This example USES multiple layers of nested code, which is very difficult to read. I find in this code that it USES indenting to mix management logic (with, ES42en-ES43en) with business logic (for, if). If you follow a specification that only USES indentation for management logic, then the core business logic should be detached immediately.

"Flat Structures are Better than nested structures." by Python Zen.

To avoid the for loop, you can use these tools

1. List parsing/generator expressions

Let's look at a simple example. This example is mainly to compile a new sequence based on an existing sequence:


result = []
for item in item_list:
  new_item = do_something_with(item)
  result.append(item)

If you like MapReduce, you can use map, or Python's list parsing:

result = [do_something_with(item) for item in item_list]

Similarly, if you just want to get an iterator, you can use generator expressions whose syntax is almost identical. (How can you not fall in love with Python's 1 sex?)

result = (do_something_with(item) for item in item_list)

2. The function

In a higher-order, more functional way to think about it, if you want to map one sequence to another, call the map function. (You can also use list parsing instead.)

doubled_list = map(lambda x: x * 2, old_list)

If you want to reduce a sequence to one element, use reduce


from functools import reduce
summation = reduce(lambda x, y: x + y, numbers)

Also, the large number of built-in features in Python can/will (I don't know if this is a good thing or a bad thing, you pick one, it's a little hard to understand without adding this sentence) consume iterators:


>>> a = list(range(10))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> all(a)
False
>>> any(a)
True
>>> max(a)
9
>>> min(a)
0
>>> list(filter(bool, a))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> set(a)
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> dict(zip(a,a))
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}
>>> sorted(a, reverse=True)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> str(a)
'[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]'
>>> sum(a)
45

3. Extract functions or expressions

The above two methods handle the simpler logic well, but what about the more complex logic? As a programmer, we abstract difficult things into functions, and this approach works here as well. If you write this code:


results = []
for item in item_list:
  # setups
  # condition
  # processing
  # calculation
  results.append(result)

Obviously you're giving too much responsibility to one piece of code. To improve, I suggest you do this:


def process_item(item):
  # setups
  # condition
  # processing
  # calculation
  return result

results = [process_item(item) for item in item_list]

What about nested for loops?


results = []
for i in range(10):
  for j in range(i):
    results.append((i, j))
 

List parsing can help you:


results = [(i, j)
      for i in range(10)
      for j in range(i)]
 

What if you want to save a lot of internal state?


# finding the max prior to the current item
a = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8]
results = []
current_max = 0
for i in a:
  current_max = max(i, current_max)
  results.append(current_max)

# results = [3, 4, 6, 6, 6, 9, 9, 9, 9, 9]
 

Let's extract an expression to implement these:


def max_generator(numbers):
  current_max = 0
  for i in numbers:
    current_max = max(i, current_max)
    yield current_max

a = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8]
results = list(max_generator(a))

"Wait a minute, you just used an for loop in the expression of that function, that's cheating!"

Okay, smart Aleck, try this one down here.

4. Don't write for loops yourself, itertools will do it for you

This module is awesome. I believe this module will cover 80% of the time you want to write down the for loop. For example, the previous example could be rewritten as follows:


result = []
for item in item_list:
  new_item = do_something_with(item)
  result.append(item)

0

Also, product(), permutations(), combinations() are available if you are iterating through the combined sequence.

conclusion

1. for loops do not need to be written in most cases.

2. for loops should be avoided to make the code more readable.

action

1. Look at your code one more time, find any places where you've intuitively written the for loop before, and think again about whether it makes sense to write the for loop one more time.

2. Share an example of how hard it is not to use the for loop.


Related articles: