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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With