1

using all, I understand this for example:

l = [1, 2, 3, 4, 5, 6]
all([n > 0 for n in l])

all takes an iterable, all good.

how come this works (no square brackets, no list comprehension):

all(n > 0 for n in l)

but this doesn't work (calling it without all):

n > 0 for n in l (SyntaxError)

and obviously, this works:

[n > 0 for n in l]

What's happening when calling any, why is it taking n > 0 for n in l as an iterable? Thanks!

Roy Ca
  • 473
  • 1
  • 3
  • 13
  • 1
    It's not just `all`, all function will interpret such parenthesis-less ones as generator if that's the only parameter they got, to quote from [Python Document](https://docs.python.org/3/reference/expressions.html#generator-expressions) - *"The parentheses can be omitted on calls with only one argument."* – jupiterbjy Apr 13 '22 at 08:02
  • @jupiterbjy - this was super clear and explains everything. can you write it as an answer? thanks! – Roy Ca Apr 13 '22 at 08:18
  • Seems like people are quite confused about whether to flag this as duplicate or not! You found your answer so that's all what matters to me. Happy python! – jupiterbjy Apr 13 '22 at 08:31

1 Answers1

0

You're passing a generator expression, and generators are iterable

The same could be done as

gen = (n > 0 for n in l)
print(all(gen))

and obviously, this works

That's a list comprehension, and not really relevant to the problem. Passing it to the all function needlessly creates an in-memory list, and thus will iterate the list more than once - one to create, and one to test all elements

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • If you call it ["generator expression"](https://docs.python.org/3/reference/expressions.html#generator-expressions), it is closer to the terminology. They were introduced in [PEP 289](https://peps.python.org/pep-0289/). – glglgl Apr 13 '22 at 08:01
  • 1
    @glglgl well, no, this was already correct, if we are not speaking informally. A generator expression evaluates to a generator object, which is what is passed. Passing an *expression* sounds like more esoteric evaluation strategies like *call by name* – juanpa.arrivillaga Apr 13 '22 at 08:12
  • I think this answers half the question. While you are correct, there is a distinction between list comprehension and generators, it does not explain why `n > 0 for n in l` throws a `SyntaxError`. – Xiddoc Apr 13 '22 at 08:18
  • I don't see the need to explain invalid syntax since the Python documentation explains the syntax perfectly fine on its own. What exactly is the expression supposed to be evaluated to? – OneCricketeer Apr 13 '22 at 08:20
  • If I were to type `"""Testing"""` on a new line, Python does not complain. However, if I type `_ for _ in []` on a new line, Python starts complaining. Why is this? Both the string and the generator are objects, why does Python only throw an error on the latter? – Xiddoc Apr 13 '22 at 08:23
  • 1
    @Xiddoc why would it complain about a string? It complains about `_ for _ in []` because that does not adhere to the [the syntax rules for generator expressions](https://docs.python.org/3/reference/expressions.html#generator-expressions) – juanpa.arrivillaga Apr 13 '22 at 08:25
  • The interpreter parses the string, and doesn't know how to handle the other expression without surrounding brackets or parenthesis, as it's not valid syntax – OneCricketeer Apr 13 '22 at 08:27
  • TIL generators need parentheses... thanks! – Xiddoc Apr 13 '22 at 08:32