标签: python-assignment-expression

":="语法和赋值表达式:什么和为什么?

PEP 572引入了为Python 3.8实现的赋值表达式.这似乎是一个非常重要的新功能,因为它将允许在理解和lambda函数中进行这种形式的赋值.

赋值表达式的语法,语义和语法规范究竟是什么?(请注意,我知道人们可以阅读PEP 572,但对于SO来说,这似乎仍然是一个有用的参考问题.)

PEP 379中关于"添加赋值表达式" 的类似想法之前被拒绝时,为什么会引入这个新的(看似相当激进的概念)呢?

python python-3.x python-3.8 python-assignment-expression

42
推荐指数
3
解决办法
6110
查看次数

使用Python 3.8中的赋值表达式,为什么我们需要在`with`中使用`as`?

现在已经接受了PEP 572,Python 3.8注定要有赋值表达式,所以我们可以使用赋值表达式with,即

with (f := open('file.txt')):
    for l in f:
        print(f)
Run Code Online (Sandbox Code Playgroud)

代替

with open('file.txt') as f:
    for l in f:
        print(f)
Run Code Online (Sandbox Code Playgroud)

它会像以前一样工作.

as关键字与withPython 3.8中的语句有什么用?这不是针对Python的禅宗:"应该有一个 - 最好只有一个 - 显而易见的方法."


当最初提出的功能,它并没有明确规定是否赋值表达式应中括号with

with f := open('file.txt'):
    for l in f:
        print(f)
Run Code Online (Sandbox Code Playgroud)

可以工作.但是,在Python 3.8a0中,

with f := open('file.txt'):
    for l in f:
        print(f)
Run Code Online (Sandbox Code Playgroud)

会引发

  File "<stdin>", line 1
    with f := open('file.txt'):
           ^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)

但括号表达式有效.

python python-3.x python-3.8 python-assignment-expression

26
推荐指数
1
解决办法
1406
查看次数

是否可以使用列表推导添加where子句?

考虑以下列表理解

[ (x,f(x)) for x in iterable if f(x) ]
Run Code Online (Sandbox Code Playgroud)

这将根据条件过滤可迭代f并返回对x,f(x).这种方法的问题f(x)是计算两次.如果我们可以这样写,那就太好了

[ (x,fx) for x in iterable if fx where fx = f(x) ]
or
[ (x,fx) for x in iterable if fx with f(x) as fx ]
Run Code Online (Sandbox Code Playgroud)

但是在python中我们必须使用嵌套的理解来编写,以避免重复调用f(x),这使得理解看起来不那么清晰

[ (x,fx) for x,fx in ( (y,f(y) for y in iterable ) if fx ]
Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以使它更加pythonic和可读?


更新

即将推出的python 3.8!PEP

# Share a subexpression between a comprehension filter clause and its output
filtered_data = [y …
Run Code Online (Sandbox Code Playgroud)

python list-comprehension python-3.x python-3.8 python-assignment-expression

22
推荐指数
3
解决办法
2万
查看次数

为什么 f 字符串需要在赋值表达式两边加上括号?

在 Python (3.11) 中,为什么在 f 字符串内使用赋值表达式(“海象运算符”)时需要用括号括起来?

例如:

#!/usr/bin/env python

from pathlib import Path

import torch


DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")

ckpt_dir = Path("/home/path/to/checkpoints")

_ckpt = next(ckpt_dir.iterdir())
print(_ckpt)
sdict = torch.load(_ckpt, map_location=DEVICE)

model_dict = sdict["state_dict"]

for k, v in model_dict.items():
    print(k)
    print(type(v))
    print(_shape := v.size())
    print(f"{(_numel := v.numel())}")
    print(_numel == torch.prod(torch.tensor(_shape)))
Run Code Online (Sandbox Code Playgroud)

上面的代码块 withprint(f"{_numel := v.numel()}")相反不会解析。

解析/AST 创建是否要求这样做?

python f-string python-assignment-expression

15
推荐指数
2
解决办法
1650
查看次数

可以使用__future__在Python 3.7中启用赋值表达式吗?

Python 3.8引入了赋值表达式,如PEP 572中所述。有没有办法在Python 3.7.x中测试此新功能?

过去,新的语言功能已使用__future__导入功能反向移植到早期的Python版本。

  • __future__赋值表达式有导入吗?
  • 如果是,功能名称是什么?
  • 如果否,是否有计划添加?(3.7将会出现一段时间)

python python-3.x python-3.7 python-3.8 python-assignment-expression

8
推荐指数
1
解决办法
527
查看次数

赋值表达式的求值顺序(海象运算符)

我有以下表达:

>>> a = 3
>>> b = 2
>>> a == (a := b)
False
Run Code Online (Sandbox Code Playgroud)

现在,a == 2手术后,正如预期的那样。结果就是我想要的,即a在分配之前与分配的 RHS 进行比较。

颠倒等号运算符的顺序会颠倒结果:

>>> a = 3
>>> b = 2
>>> (a := b) == a
True
Run Code Online (Sandbox Code Playgroud)

PEP-572 相对优先级部分中似乎没有任何与此极端情况直接相关的内容。下一节,更改评估顺序提到评估顺序是从左到右。这就是这里发生的情况吗(存储 的值a,更新它,然后比较与 update a,然后与其新值进行比较)?

这种行为是在哪里定义的,它的可靠性如何?

python python-assignment-expression walrus-operator

8
推荐指数
1
解决办法
670
查看次数

如何避免推导式中 Python 赋值表达式的泄漏

Effective Python一书中,作者建议使用赋值表达式来避免理解中的冗余,例如:

def fun(i):
    return 2 * i

result = {x: y for x in [0, 1, 2, 3] if (y := fun(x)) > 3}
Run Code Online (Sandbox Code Playgroud)

代替

result = {x: fun(x) for x in [0, 1, 2, 3] if fun(x) > 3}
Run Code Online (Sandbox Code Playgroud)

result有价值{2: 4, 3: 6}

作者指出

如果推导式在推导式的值部分使用海象运算符并且没有条件,它会将循环变量泄漏到包含范围中。[...] 最好不要泄漏循环变量,因此我建议仅在推导式的条件部分使用赋值表达式。

然而,在上面的例子中, y在程序结束时设置为 6。因此,赋值表达式中的变量泄漏了,尽管它是在条件中定义的。

列表推导式也会发生同样的事情:

>>> _ = [(x, leak) for x in range(4) if (leak := 2 * x) > 3]
>>> leak
6
Run Code Online (Sandbox Code Playgroud)

甚至对于生成器表达式:

>>> …
Run Code Online (Sandbox Code Playgroud)

python python-assignment-expression

6
推荐指数
1
解决办法
111
查看次数

如何使用Python 3.8 alpha中引入的赋值表达式重写此简单循环?

在我看来,将经典的while循环与Assignment-expressions -loops互换可以使代码看起来很棒不是那么简单。

考虑example1

>>> a = 0
>>> while (a := a+1) < 10:
...     print(a)
... 
1
2
3
4
5
6
7
8
9
Run Code Online (Sandbox Code Playgroud)

example2

>>> a = 0
>>> while a < 10:
...     print(a)
...     a += 1
... 
0
1
2
3
4
5
6
7
8
9
Run Code Online (Sandbox Code Playgroud)

您将如何修改example1以具有相同的输出(不跳过0example2?(a = 0当然,无需更改)

python python-3.8 python-assignment-expression

5
推荐指数
1
解决办法
1095
查看次数

在Python中使用赋值表达式时,如何完成赋值语句“ x = y:= f(x)”?

在Twitter上阅读

#Python新闻:Guido接受了PEP572。Python现在具有赋值表达式。

 if (match := (pattern.search) pattern.search(data)) is not None:
    print((match.group) mo.group(1))

 filtered_data = [y for x in data if (y := f(x)) is not None]
Run Code Online (Sandbox Code Playgroud)

(在第二行代码中更正我的)

如前所述,PEP 572-赋值表达式描述了它在Python 3.8中的存在:

这是创建一种使用符号在表达式中分配变量的方法的建议NAME := expr

我已经遍历了描述和示例,并且看到了这是避免重复调用或分配的便捷方法,因此可以代替:

match1 = pattern1.match(data)
match2 = pattern2.match(data)
if match1:
    return match1.group(1)
elif match2:
    return match2.group(2)
Run Code Online (Sandbox Code Playgroud)

或更有效的:

match1 = pattern1.match(data)
if match1:
    return match1.group(1)
else:
    match2 = pattern2.match(data)
    if match2:
        return match2.group(2)
Run Code Online (Sandbox Code Playgroud)

现在可以说:

if match1 := pattern1.match(data):
    return …
Run Code Online (Sandbox Code Playgroud)

python pep python-3.8 python-assignment-expression

4
推荐指数
1
解决办法
216
查看次数

了解新python:=运算符的原因

这是一个元编程问题:我想了解为什么python开发人员在new中引入了另一个运算符:=。我知道这是干什么的 但是,我想知道为什么开发人员选择一个新的符号而不是重复使用例如as运算符。

即为什么认为最好写

while (command := input("> ")) != "quit":
    print("You entered:", command)
Run Code Online (Sandbox Code Playgroud)

而不是

while input("> ") as command != "quit":
    print("You entered:", command)
Run Code Online (Sandbox Code Playgroud)

python language-design python-3.x python-3.8 python-assignment-expression

2
推荐指数
1
解决办法
89
查看次数

“海象操作员”分配的多个条件

我想知道是否可以使用“海象运算符”根据某些条件以及现有条件来分配值。例如,post_url如果该字符串包含某个子字符串,则将该字符串分配给:

if post_url := data.get("Post url") and ("youtube" in data.get("Post url")):
    # Do something with post_url
else:
    # Do something else
Run Code Online (Sandbox Code Playgroud)

然而,这只是post_url由于操作的评估而分配布尔值and

python python-3.8 python-assignment-expression

2
推荐指数
1
解决办法
2701
查看次数

为什么Python不能使用as关键字来进行赋值表达式?

Python 3.8引入了“海象运算符”:=来进行赋值表达式。我认为他们考虑过使用该关键字as但拒绝了。是否存在as阻止将其用于赋值表达式的现有语法情况?

要使用 Python 文档中的示例:

# Actual Python 3.8 syntax
if (n := len(a)) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")

# Why not this?
if (len(a) an n) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")
Run Code Online (Sandbox Code Playgroud)

这是另一个例子:

# Actual Python 3.8 syntax
while (block := f.read(256)) != '':
    process(block)

# Why not this?
while f.read(256) as block:
    process(block)
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-3.8 python-assignment-expression

-2
推荐指数
1
解决办法
74
查看次数