Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

good style to introduce python variables within a loop

Tags:

python

I have a C++ background and I'm learning Python. I am writing code which needs to extract a particular value from a for loop:

seventh_value = None   # ** my question is about this line
for index in range(1, 10):
    value = f(index)
    # we have a special interest in the seventh value
    if index == 7:
        seventh_value = value
    # (do other things with value here)

# make use of seventh_value here

In C++ I'd need to declare seventh_value before the for loop to ensure its scope is not limited to the for loop. In Python I do not need to do this. My question is whether it's good style to omit the initial assignment to seventh_value.

I understand that if the loop doesn't iterate at least 7 times then I can avoid a NameError by assigning to seventh_value prior to the loop. Let's assume that it is clear it will iterate at least 7 times (as in the above example where I've hard-coded 10 iterations).

I also understand that there may be other ways to extract a particular value from an iteration. I'm really just wondering about whether it's good style to introduce variables before a loop if they will be used after the loop.

The code I wrote above looks clear to me, but I think I'm just seeing it with C++ eyes.

like image 357
nonagon Avatar asked Aug 12 '16 17:08

nonagon


2 Answers

This is a fine approach to set the value to None before the for-loop. Do not worry too much. Personally, I feel as long as code is readable by someone who has no idea at all -- it is fine.

That being said, there's a slightly better (pythonic) way to avoid the problem altogether. Note that the following will not do anything with the value at every iteration -- just the "special interest" part. Further, I am assuming f(..) does not cause any side-effects (like changes states of variables outside (like global variables). If it does, the line below is definitely not for you.

seventh_value = next(f(i) for i in range(1,10) if i == 7)

The above construct run until i==7, and calls f(i) only when i=7 never else.

like image 107
UltraInstinct Avatar answered Oct 12 '22 23:10

UltraInstinct


It's only partially a matter of style. You need to do something to ensure your code doesn't raise an (uncaught) NameError following the loop, so your two choices are

  1. Ensure that the NameError cannot happen by making an unconditional assignment to seventh_value.

  2. Wrap the code that accesses seventh_value in a try block to catch and (presumably) ignore the possible NameError.

View from this perspective, and without knowing more about your code, I think you would agree that #1 is preferable.

like image 21
chepner Avatar answered Oct 13 '22 00:10

chepner