> Yes but then it's the same as defining a generator-function.

List comprehensions are already the same as other things, but they're nice 
anyway. `lambda` is the same as defining a function, but it's nice too. 
Syntactic sugar is helpful sometimes. I think this:

    clean = [
        for line in lines:
            stripped = line.strip()
            if stripped:
                yield stripped
    ]

is easily nicer than this:

    def clean_lines():
        for line in lines:
            line = line.strip()
            if line:
                yield line
    
    clean = list(clean_lines())

And this:

    new_matrix = [
        for row in matrix: yield [
            for cell in row:
                try:
                    yield f(cell)
                except ValueError:
                    yield 0
        ]
    ]
    
is nicer than any of these:

    new_matrix = []
    for row in matrix:
        def new_row():
            for cell in row:
                try:
                    yield f(cell)
                except ValueError:
                    yield 0

        new_matrix.append(list(new_row()))

    ----

    def new_row(row):
        for cell in row:
            try:
                yield f(cell)
            except ValueError:
                yield 0

    new_matrix = [list(new_row(row)) for row in matrix]

    ----
    
    def safe_f(cell):
        try:
            return f(cell)
        except ValueError:
            return 0

    new_matrix = [
        [
            safe_f(cell)
            for cell in row
        ]
        for row in matrix
    ]

> > I think it's ambiguous, like in this example:
> clean = [
>         for line in lines:
>             stripped = line.strip()
>             if stripped:
>                 stripped
>     ]
> what says that it's the last stripped that should be yielded?

Because it's the only statement that *can* be yielded. The `yield` is implicit 
when there's exactly one statement you can put it in front of. You can't `yield 
stripped = line.strip()`. You can technically have `stripped = yield 
line.strip()` but we ignore those possibilities.

> > If that function is the whole statement and there is
> > no other expression statement in the comprehension, it will be yielded. I 
> > can't tell if
> > there's more to your question.
> > Imagine this one:
> foo = [
>     for x in range(5):
>         f(x)
>         if x % 2:
>             x
> ]
> what will be the result?

It will be a SyntaxError, because it's ambiguous.

Here's a new idea: `yield` is only optional in inline comprehensions, i.e. 
where the loop body consists entirely of a single expression. So for example 
this is allowed:

    new_row = [for cell in row: f(cell)]

but this is not:

    new_row = [
        for cell in row:
            thing = g(cell)
            f(thing)
    ]

Instead the user must write `yield f(thing)` at the end.

This would mean that you only need to add `yield` when the comprehension is 
already somewhat long so it's less significant, and there's only one very 
simple special case to learn about.
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/4QSZ5LCWKBDHFR3VRMPVAV2C5JIODSEP/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to