results = [(x, y, x/y) for x in input_data if (y := f(x)) > 0]
results = [(x, y, x/y) for x in input_data for y in [f(x)] if y > 0]
stuff = [[y := f(x), x/y] for x in range(5)]
stuff = [[y, x/y] for x in range(5) for y in [f(x)]]
This idiom looks unusual for you? But this is a legal Python syntax, and
it is not more unusual than the new walrus operator. This idiom is not
commonly used because there is very little need of using above examples
in real code. And I'm sure that the walrus operator in comprehension
will be very rare unless PEP 572 will encourage writing complicated
comprehensions. Most users prefer to write an explicit loop.
I want to remember that PEP 572 started from the discussion on Python-ideas which proposed a syntax for writing the following code as a comprehension:
smooth_signal = []
average = initial_value
for xt in signal:
average = (1-decay)*average + decay*xt
smooth_signal.append(average)
Using the "for in []" idiom this can be written (if you prefer
comprehensions) as:
smooth_signal = [average
for average in [initial_value]
for x in signal
for average in [(1-decay)*average + decay*x]]
Try now to write this using PEP 572. The walrus operator turned to be
less suitable for solving the original problem because it doesn't help
to initialize the initial value.
Examples from PEP 572:
# Loop-and-a-half
while (command := input("> ")) != "quit":
print("You entered:", command)
The straightforward way:
while True:
command = input("> ")
if command == "quit": break
print("You entered:", command)
The clever way:
for command in iter(lambda: input("> "), "quit"):
print("You entered:", command)
# Capturing regular expression match objects
# See, for instance, Lib/pydoc.py, which uses a multiline spelling
# of this effect
if match := re.search(pat, text):
print("Found:", match.group(0))
# The same syntax chains nicely into 'elif' statements, unlike the
# equivalent using assignment statements.
elif match := re.search(otherpat, text):
print("Alternate found:", match.group(0))
elif match := re.search(third, text):
print("Fallback found:", match.group(0))
It may be more efficient to use a single regular expression which consists of multiple or-ed patterns marked as different groups. For example see the cute regex-based tokenizer in gettext.py:
_token_pattern = re.compile(r"""
(?P<WHITESPACES>[ \t]+) | # spaces and horizontal
tabs
(?P<NUMBER>[0-9]+\b) | # decimal integer
(?P<NAME>n\b) | # only n is allowed
(?P<PARENTHESIS>[()]) |
(?P<OPERATOR>[-*/%+?:]|[><!]=?|==|&&|\|\|) | # !, *, /, %, +, -, <, >,
# <=, >=, ==, !=, &&, ||,
# ? :
# unary and bitwise ops
# not allowed
(?P<INVALID>\w+|.) # invalid token
""", re.VERBOSE|re.DOTALL)
def _tokenize(plural):
for mo in re.finditer(_token_pattern, plural):
kind = mo.lastgroup
if kind == 'WHITESPACES':
continue
value = mo.group(kind)
if kind == 'INVALID':
raise ValueError('invalid token in plural form: %s' % value)
yield value
yield ''
I have not found any code similar to the PEP 572 example in pydoc.py. It has different code:
pattern = re.compile(r'\b((http|ftp)://\S+[\w/]|'
r'RFC[- ]?(\d+)|'
r'PEP[- ]?(\d+)|'
r'(self\.)?(\w+))')
...
start, end = match.span()
results.append(escape(text[here:start]))
all, scheme, rfc, pep, selfdot, name = match.groups()
if scheme:
url = escape(all).replace('"', '"')
results.append('<a href="%s">%s</a>' % (url, url))
elif rfc:
url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc)
results.append('<a href="%s">%s</a>' % (url, escape(all)))
elif pep:
...It doesn't look as a sequence of re.search() calls. It is more clear and efficient, and using the assignment expression will not make it better.
# Reading socket data until an empty string is returned
while data := sock.recv():
print("Received data:", data)
for data in iter(sock.recv, b''):
print("Received data:", data)
if pid := os.fork():
# Parent code
else:
# Child code
pid = os.fork()
if pid:
# Parent code
else:
# Child code
It looks to me that there is no use case for PEP 572. It just makes
Python worse.
_______________________________________________ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
