4
def strange_syntax(stuff):
    return ".".join(item for item in stuff)

How (and why) works this code? What happens here? Normally I can't use this syntax. Also, this syntax doesn't exist if it's not inside some function as an argument.

I know, I could do the same with:

def normal_syntax(stuff):
    return ".".join(stuff)
Georgy
  • 12,464
  • 7
  • 65
  • 73
Qback
  • 4,310
  • 3
  • 25
  • 38

2 Answers2

4

This is called a generator expression.

It works just like a list comprehension (but evaluating the iterated objects lazily and not building a new list from them), but you use parentheses instead of brackets to create them. And you can drop the parentheses in a function call that only has one argument.

In your specific case, there is no need for a generator expression (as you noted) - (item for item in stuff) gives the same result as stuff. Those expressions start making sense when doing something with the items like (item.strip() for item in stuff) (map) or (item for item in stuff if item.isdigit()) (filter) etc.

Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
  • Thanks. I also found thread about generators here https://stackoverflow.com/questions/1756096/understanding-generators-in-python It's nicely explained there. – Qback Jan 11 '18 at 11:25
3

When used in a function call, the syntax:

f(a for a in b)

implicitly is compiled as a generator, meaning

f((a for a in b))

This is just syntactic sugar, to make the program look nicer. It doesn't make much sense to write directly in the console

>>>a for a in b

because it's unclear if you want to create a generator, or perform a regular loop. In this case you must use the outer ().

kabanus
  • 24,623
  • 6
  • 41
  • 74
  • Is it possible to do sth like this: `format((key(i) for i in dict_var) = func(i))`? What I want it to be is, with `dict_var` being `{"key1": "value1", "key2": "value2"}` `sql.SQL('query').format(key1=sql.Identifier('value1'), key2=sql.Identifier('value2'))` (`from psycopg2 import sql` was used) – jimmymcheung Dec 22 '22 at 12:25