Yes, this is bad style. A list comprehension is to build a list. You're building a list full of None
s and then throwing it away. Your actual desired result is a side effect of this effort.
Why not define foo
using the list comprehension in the first place?
foo = [sum(i,x) for i, x in enumerate(bar_list)]
If it is not to be a list but some other container class, as you mentioned in a comment on another answer, write that class to accept an iterable in its constructor (or, if it's not your code, subclass it to do so), then pass it a generator expression:
foo = MyContainer(sum(i, x) for i, x in enumerate(bar_list))
If foo
already has some value and you wish to append new items:
foo.extend(sum(i,x) for i, x in enumerate(bar_list))
If you really want to use append()
and don't want to use a for
loop for some reason then you can use this construction; the generator expression will at least avoid wasting memory and CPU cycles on a list you don't want:
any(foo.append(sum(i, x)) for i, x in enumerate(bar_list))
But this is a good deal less clear than a regular for
loop, and there's still some extra work being done: any
is testing the return value of foo.append()
on each iteration. You can write a function to consume the iterator and eliminate that check; the fastest way uses a zero-length collections.deque
:
from collections import deque
do = deque([], maxlen=0).extend
do(foo.append(sum(i, x)) for i, x in enumerate(bar_list))
This is actually fairly readable, but I believe it's not actually any faster than any()
and requires an extra import. However, either do()
or any()
is a little faster than a for
loop, if that is a concern.