How does this piece of code work?

Asked

Viewed 62 times

3

My doubt is more precisely in line "8", line containing the for. I’ve never seen one used this way. I understood the logic of the line, but the operation of this iteration made me very curious.

import csv

%precision 2

with open('mpg.csv') as csvfile:
    mpg = list(csv.DictReader(csvfile))

sum(float(d['cty']) for d in mpg) / len(mpg)
  • 1

    pythonic way of making it be in one line, look at another basic example in this answer here

  • Python’s "for" structure, while being very robust, is highly flexible. And so it accepts several ways to be implemented. This is one of the pythonic ways to implement the for in one line. See outros examples here

1 answer

2


The expression of the type

(func(e) for e in seq)

is called generator expression (or Generator Expression in English). It is used to create a sequence by taking the elements of another sequence and modifying them - in this case, picking up each element e of seq and passing them on to the function func.

Note that the returned object is a type of everlasting (more specifically, a generator-type object):

strings = ['1', '2', '3']
nums = (int(s) for s in strings)
print(nums)  
# output: <generator object <genexpr> at 0x7f8565e11200>

Generators have some special properties that don’t come to the case now; briefly, you can iterate on them once, and to make a new iteration it is necessary to recreate it as it is "consumed".

The function sum accepts any type of iterable, including generators. Therefore, when writing something like

strings = ['1', '2', '3']
nums = (int(s) for s in strings)
sum(nums)

I’m summing up all the elements inside the iterável (generator) nums.

And also note that I don’t necessarily need to define the variable nums. It is possible to build the generator and consume it in the same line:

strings = ['1', '2', '3']
sum(int(s) for s in strings)

The last one converts all elements of the sequence strings for integers and sums at once. In this case it is not strictly necessary to use parentheses around the generator expression for a simple syntax that Python allows.

If you were to try to replicate this behavior with a "traditional" loop, you would do something like:

strings = ['1', '2', '3']
nums = []
for s in strings:
    n = int(s)
    nums.append(n)
sum(nums)

Which is much less practical, in my opinion. (And it’s not strictly equivalent, since nums is now a list, not a generator, even if the end result is identical).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.