On several occasions I've wanted python syntax for short-circuiting list comprehensions or generator expressions.
Here is a simple list comprehension, and the equivalent for loop in python:
my_list = [1, 2, 3, 'potato', 4, 5]
[x for x in my_list if x != 'potato']
result = []
for element in my_list:
if element != 'potato':
result.append(element)
There isn't support in the language for a comprehension which short-circuits. Proposed syntax, and equivalent for loop in python:
[x for x in my_list while x != 'potato']
# --> [1, 2, 3]
result = []
for element in my_list:
if element != 'potato':
result.append(element)
else:
break
It should work with arbitrary iterables, including infinite sequences, and be extendible to generator expression syntax. I am aware of list(itertools.takewhile(lambda x: x != 'potato'), my_list)
as an option, but:
- it's not particularly pythonic - not as readable as a while comprehension
- it probably can't be as efficient or fast as a CPython comprehension
- it requires an additional step to transform the output, whereas that can be put into a comprehension directly, e.g.
[x.lower() for x in mylist]
- even the original author doesn't seem to like it much.
My question is, was there any theoretical wrinkle about why it's not a good idea to extend the grammar to this use case, or is it just not possible because python dev think it would be rarely useful? It seems like a simple addition to the language, and a useful feature, but I'm probably overlooking some hidden subtleties or complications.
result = []; any(x=='potato' or result.append(x) for x in my_list)
. Hmm...no I think this is worse than takewhile :) – Medallistfilterfalse
, OP wants to stop all appending after first 'potato' is found. Try:found = []; result = []; any(x=='potato' and not found.append(x) or result.append(x) if not found else None for x in my_list)
– Cata[x if x != 'potato' else break for x in my_list]
– Medallistany
shortcircuits it – Medallistlist(iter(iter(my_list).next, "potato"))
sounds funny when you say it out loud – Medallist