Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't this list comprehension do what I expect it to do?

The original list project_keys = sorted(projects.keys()) is [101, 102, 103, 104, 105, 106, 107, 108, 109, 110] where the following projects were deemed invalid this year: 108, 109, 110.

Thus:

for project in projects.itervalues():
# The projects dictionary is mapped to the Project class
    if project.invalid:
    # Where invalid is a Bool parameter in the Project class
     project_keys.remove(project.proj_id)  

print project_keys

This will return a list of integers (which are project id's) as such:

[101, 102, 103, 104, 105, 106, 107]

Sweet.

Now, I wanted it try the same thing using a list comprehension.

project_keys = [project_keys.remove(project.proj_id) for project in projects.itervalues() if project.invalid  

print project_keys

This returns:

[None, None, None]

So I'm populating a list with the same number as the removed elements but they're Nones?

Can someone point out what I'm doing wrong?

Additionally, why would I use a list comprehension over the for-if block at the top? Conciseness? Looks nicer?

like image 933
PizzAzzra Avatar asked Dec 17 '25 18:12

PizzAzzra


1 Answers

Your list comprehension works using side-effects. Just executing it should update project_keys to give the result you want.

[project_keys.remove(project.proj_id)
 for project in projects.itervalues()
 if project.invalid]

The return value from remove is None. Assigning the result of the list comprehension to project_keys is where you are going wrong.

A simple loop is probably clearer here though. A list comprehension that uses side-effects can be confusing.

However you can solve your problem in a slightly different way:

project_keys = sorted(project.proj_id
                      for project in projects.itervalues()
                      if not project.invalid)

This keeps the projects you are interested in, instead of removing those that you're not interested in. The example I gave above uses a generator expression instead of a list comprehension, but it would work with either.

like image 177
Mark Byers Avatar answered Dec 20 '25 08:12

Mark Byers



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!