Click here for the first post, which contains the context of this series.
Item #06: Prefer multiple assignment unpacking over indexing.
Prefer
first_name, middle_name, last_name = full_name
over
first_name = full_name[0]
middle_name = full_name[1]
last_name = full_name[2]
Item #07: Prefer enumerate over range.
Prefer
for i, item in enumerate(my_list):
some_function(i, item)
over
for i in range(len(my_list)):
some_function(i, my_list[i])
Item #08: Use zip to process iterators in parallel.
Prefer
for expected, actual in zip(expected_results, actual_results):
assert expected == actual
over
for i in range(len(expected_results)):
# error prone if len(expected_results) != len(actual_results)
assert expected_results[i] == actual_results[i]
Note that zip(A, B) iterates at most min(len(A), len(B)) times.
Item #09: Avoid else blocks after for and while loops.
Suppose that you want to check whether a list my_list contains an item target. Although this can be accomplished as follows
for item in my_list:
if item == target:
print('target found')
break
else:
print('target not found')
avoid doing this (perhaps using a flag).
Item #10: Prevent repetition with assignment expressions.
Consider the following common pattern
info = get_info()
if has_property(info):
do_something_with(info)
else:
do_something_else()
It suggests that info is used beyond the scope of if. If it is not, then remove the ambiguity as follows
if has_property(info := get_info()):
do_something_with(info)
else:
do_something_else()
This way, the scope of info is restricted to if.