Local variable definition in Python list comprehension

Chris Angelico rosuav at gmail.com
Thu Sep 1 17:01:31 EDT 2022


On Fri, 2 Sept 2022 at 06:55, James Tsai <jamestztsai at gmail.com> wrote:
>
> 在 2022年9月1日星期四 UTC+2 18:34:36,<ery... at gmail.com> 写道:
> > On 9/1/22, James Tsai <james... at gmail.com> wrote:
> > >
> > > I find it very useful if I am allowed to define new local variables in a
> > > list comprehension. For example, I wish to have something like
> > > [(x, y) for x in range(10) for y := x ** 2 if x + y < 80], or
> > > [(x, y) for x in range(10) with y := x ** 2 if x + y < 80].
> > >
> > > For now this functionality can be achieved by writing
> > > [(x, y) for x in range(10) for y in [x ** 2] if x + y < 80].
> > You can assign a local variable in the `if` expression. For example:
> >
> > >>> [(x, y) for x in range(10) if x + (y := x**2) < 30]
> > [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16)]
>
> Yeah this works great but like [(x, y) for x in range(10) for y in [x**2]] I written before, is kind of a hack. And if initially I do not need an "if" condition in the list comprehension, this becomes less convenient. I still can write
> >>> [(x, y) for x in range(10) if (y := x**2) or True]
>
> But I wonder if Python could have a specific syntax to support this.
>

But why would you need to assign to y in that example? If you're using
it more than once, you can use :=, and if you aren't, you don't need
to. But do be aware that := does not create a comprehension-local name
binding, but a nonlocal instead.

> No but very often when I have written a neat list/dict/set comprehension, I find it very necessary
> to define local variable(s) to make it more clear and concise. Otherwise I have to break it down
> to several incrementally indented lines of for loops, if statements, and variable assignments,
> which I think look less nice.

Well, if it's outgrown a list comp, write it on multiple lines. Like I
said, not everything has to be a one-liner.

ChrisA


More information about the Python-list mailing list