Basic Nested Dictionary in a Loop

Peter Otten __peter__ at web.de
Tue Apr 4 02:41:09 EDT 2017


Ganesh Pal wrote:

>>
>>
>> Whenever you feel the urge to write range(len(whatever)) -- resist that
>> temptation, and you'll end up with better Python code ;)
>>
>>
> Thanks for this suggestion but for my better understanding can  explain
> this further even Steve did point the same mistake.

It's not directly a mistake, it's just that programming against a smaller 
interface makes your code more flexible and more readable.

Readability:

items = [...]
for i in range(len(items)):
    ...

Are list entries replaced? We cannot know without inspecting the for suite.

items = [...]
for item in items:
    ...

Are list entries replaced? No.

Flexibility:

def give_raise(employees, amount):
    for i in range(len(items)):
        employee = employees[i]
        employee.payment += amount

employees = [...]
give_raise(employees, 10)

Now let's adapt the code to raise the payment of some employees:

male_employees = [
     employees[i] for i in range(len(employees)) 
     if e.sex == "male"
]
give_raise(male_emplyees, 10)

We need a helper list, basically because there is a len() call inside the 
give_raise() function. If we rewrite the function in an idiomatic way

def give_raise(employees, amount):
    for employee in employees:
        employee.payment += amount

it will become not just more concise, the calling code no longer needs to 
build the intermediate list. Instead we save the extra memory and pass a 
generator expression:

give_raise((e for e in employees if e.sex == "female"), 10)

In a similar way you can write code that iterates over data that is lazily 
read into memory, like lines in a file

# wrong, reads the whole file into memory
lines = open(...).readlines()
for i in range(len(lines)):
    process(lines[i])

# idiomatic, read the lines as needed
for line in open(...):
    process(line)

or records from a database.





More information about the Python-list mailing list