36

What is the advantage of using a list comprehension over a for loop in Python?

Is it mainly to make it more humanly readable, or are there other reasons to use a list comprehension instead of a loop?

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
David
  • 417
  • 1
  • 4
  • 7
  • 2
    I think they're faster than for loops in most (if not all) cases. That is, aside from the beauty of them :) – BenDundee May 02 '13 at 15:21
  • 1
    "We expect answers to be supported by facts, references, or specific expertise, but this question will likely solicit debate, arguments, polling, or extended discussion." Seems that this question can be supported with "specific facts [and] specific expertise". Marking it to be closed is BS, IMO. – BenDundee May 02 '13 at 15:37
  • 1
    On second thought, that's not a "not constructive" question, moreover, has not been asked in this form previously (comparing to [this](http://stackoverflow.com/q/1247486/770830)), voting for reopening. – bereal May 02 '13 at 15:40
  • 1
    @MartijnPieters: So it's basically down to semantics? Stuff like this really frustrates me on SO: it's clear (to me, at least) that the question is asked in well-posed way. Maybe David and I are equally inept at reading the rules, but I somehow doubt it... – BenDundee May 02 '13 at 15:55
  • @BenDundee: There can be an endless number of advantages, because advantages are in the eye of the beholder. – Martijn Pieters May 02 '13 at 15:57
  • @bereal: That other question is much better constrained. We can edit this question to ask if *list comps have some other advantage over a `for` loop other than readability*, for example. That'd be *much* more constrained in scope. – Martijn Pieters May 02 '13 at 15:59
  • @MartijnPieters: so you're closing the question because there isn't a single right answer? Looks like there's a bit of work to do around the site, then... – BenDundee May 02 '13 at 16:01
  • @BenDundee: If you want to discuss what makes a question constructive or not, you can do so on [Meta]. But yes, we have some work to do around the site. Pitch in! – Martijn Pieters May 02 '13 at 16:04
  • The link is broken: *"404 Not Found"*. – Peter Mortensen Dec 14 '22 at 21:12

1 Answers1

58

List comprehensions are more compact and faster than an explicit for loop building a list:

def slower():
    result = []
    for elem in some_iterable:
        result.append(elem)
    return result

def faster():
    return [elem for elem in some_iterable]

This is because calling .append() on a list causes the list object to grow (in chunks) to make space for new elements individually, while the list comprehension gathers all elements first before creating the list to fit the elements in one go:

>>> some_iterable = range(1000)
>>> import timeit
>>> timeit.timeit('f()', 'from __main__ import slower as f', number=10000)
1.4456570148468018
>>> timeit.timeit('f()', 'from __main__ import faster as f', number=10000)
0.49323201179504395

However, this does not mean you should start using list comprehensions for everything! A list comprehension will still build a list object; if you are using a list comprehension just because it gives you a one-line loop, think again. You are probably wasting cycles building a list object that you then discard again. Just stick to a normal for loop in that case.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    They also make the above code clearer. (I think you cover that already by calling them "explicit".) – Steven Rumbalski May 02 '13 at 15:27
  • 1
    It's worth noting (even though the question only asks for advantages) that overuse of list comps can easily lead to worse code, both in efficiencies and readability/maintainability. Too many times I've seen multiple list comps going through the same loop, one following the other. I've also seen list comps used for intermediate results, which should be done with generator comps. You can construct a very complex list comprehension that is still efficient using a series of generator comps ending in a list comp. They are convenient and fast in isolated cases, but be careful of context! – DylanYoung Apr 03 '18 at 16:59
  • 2
    @DylanYoung: absolutely, you should never use a list comprehension for the side effects. If you are using a list comprehension *just because it'll loop*, you are wasting cycles on building a list object. – Martijn Pieters Apr 03 '18 at 17:16
  • 1
    Absolutely! Not just the side effects though. Often you want to construct multiple lists (or dicts, etc) from the same source list (e.g. for back referencing). I've often seen this done as a series of comprehensions (list and/or dict and/or set) when a single loop would have done for constructing them all. – DylanYoung Apr 03 '18 at 18:14
  • @DylanYung: a single loop wouldn’t be any more efficient though. The same algorithmic complexity applies, so it’ll come down to constant factors. List comprehensions win on constant factors. – Martijn Pieters Apr 03 '18 at 18:25