# Filtering List Comprehensions

Copied!
Happy Pythoning!

In this lesson, you’ll see that list comprehensions are often recommended by Python core developers as a more Pythonic solution than the filter() function you used in the previous lesson.

You can also skip the middle man and use a generator expression to get the same result but not create a list in the process. A generator expressions defines an ad hoc iterator that then produces values for you without first creating a list, and then creating a tuple from that list, and then destroying the list again, so it’s more memory efficient.

espdave4

For line:

print(tuple(x for x in scientists if x.nobel is True))
TypeError: 'tuple' object is not callable

Any reason why?

George Yeboah

u missed the the tuple parentenses like the this print(tuple((x for x in scientists if x.nobel is True)))

Anh Lu

So if tuple(filter(lambda x: x.nobel, scientist)) and tuple(x for x in scientist if x.nobel) return the same result, when should we use one over the other?

Comprehensions are generally deemed as more Pythonic, so I’d go with this version:

tuple(x for x in scientist if x.nobel)

(Technically, you’re writing a generator expression in this case but syntactically they’re the same as list comprehensions.)

quitobarajas

seems a bit complicated but I’ll get the hang of it!

When we use list comprehensions the result is list, so can it mutable?

Bartosz Zaczyński RP Team

@PrasadChaskar Yeah, absolutely. You just need to store the resulting value in a variable somewhere to be able to mutate it:

>>> squares = [i**2 for i in range(1, 10)]
>>> squares[1] = "foobar"
>>> squares
[1, 'foobar', 9, 16, 25, 36, 49, 64, 81]

Maram-dev

So the tuple(x for x in scientists if x.noble is True) didn’t generate the error you got from creating tuple(1,2,3), because the expression (x for x....) was taken for a single argument, right?

I’m a little bit new to Python, so excuse my sometimes stupid questions :)

Martin Breuss RP Team

Hi @Mar-dev, that’s a great question! :D

And you’re right in your assumption. Using tuple() converts an iterable to a tuple and it takes only one argument as its input. The error message tells you that with tuple(1,2,3) you’re passing the three arguments 1, 2, and 3, instead:

TypeError: tuple expected at most 1 argument, got 3

But what Dan did initially with the following line of code:

tuple(x for x in scientists if x.nobel is True)

is that he created a generator object, which is a single, iterable object, and then he passed only that one argument to tuple(). So it worked ✨ :)

Maram-dev

Hey Martin, Thank you for the explanation! I will read more into generator objects, I still need to wrap my mind around them.

damipatira

Cheers to List Comprehensions !! I have a feeling we will be good friends :D

to join the conversation.