为什么Python中没有++和——运算符?


当前回答

Maybe a better question would be to ask why do these operators exist in C. K&R calls increment and decrement operators 'unusual' (Section 2.8page 46). The Introduction calls them 'more concise and often more efficient'. I suspect that the fact that these operations always come up in pointer manipulation also has played a part in their introduction. In Python it has been probably decided that it made no sense to try to optimise increments (in fact I just did a test in C, and it seems that the gcc-generated assembly uses addl instead of incl in both cases) and there is no pointer arithmetic; so it would have been just One More Way to Do It and we know Python loathes that.

其他回答

我知道这是一个旧线程,但最常见的用例++ I没有涵盖,即手动索引集时,没有提供索引。这种情况就是python提供enumerate()的原因

示例:在任何给定的语言中,当你使用像foreach这样的构造来遍历一个集合时——为了示例的目的,我们甚至会说它是一个无序的集合,你需要一个唯一的索引来区分它们

i = 0
stuff = {'a': 'b', 'c': 'd', 'e': 'f'}
uniquestuff = {}
for key, val in stuff.items() :
  uniquestuff[key] = '{0}{1}'.format(val, i)
  i += 1

在这种情况下,python提供了一个枚举方法,例如。

for i, (key, val) in enumerate(stuff.items()) :

要完成那一页上已经很好的答案:

让我们假设我们决定这样做,前缀(++i)将打破一元的+和-操作符。

现在,用++或——作为前缀没有任何作用,因为它使一元加运算符两次(没有任何作用)或一元减运算符两次(两次:取消自身)

>>> i=12
>>> ++i
12
>>> --i
12

所以这可能会打破这个逻辑。

现在,如果需要它来进行列表推导或lambdas,从python 3.8开始,可以使用新的:=赋值操作符(PEP572)

预递增a并赋值给b:

>>> a = 1
>>> b = (a:=a+1)
>>> b
2
>>> a
2

后增量只需要通过减1来弥补过早的加法:

>>> a = 1
>>> b = (a:=a+1)-1
>>> b
1
>>> a
2

当然,我们可以说“Guido只是决定那样做”,但我认为问题实际上是关于这个决定的原因。我认为有以下几个原因:

它将语句和表达式混合在一起,这不是好的实践。参见http://norvig.com/python-iaq.html 它通常鼓励人们编写可读性较差的代码 语言实现中的额外复杂性,如前所述,这在Python中是不必要的

我对python为什么没有++操作符的理解如下:当你用python写这个时,a=b=c=1,你会得到三个变量(标签)指向同一个对象(值为1)。你可以使用id函数来验证这一点,它将返回一个对象内存地址:

In [19]: id(a)
Out[19]: 34019256

In [20]: id(b)
Out[20]: 34019256

In [21]: id(c)
Out[21]: 34019256

所有三个变量(标签)都指向同一个对象。现在增加变量之一,看看它是如何影响内存地址的:

In [22] a = a + 1

In [23]: id(a)
Out[23]: 34019232

In [24]: id(b)
Out[24]: 34019256

In [25]: id(c)
Out[25]: 34019256

你可以看到变量a现在指向另一个对象,变量b和c。因为你已经使用了a = a + 1,这是明确的。换句话说,你将完全另一个对象赋值给标签a。想象一下,你可以写一个++,这将表明你没有给变量赋值一个新对象,而是给旧对象赋值。所有这些东西都是为了尽量减少混淆。为了更好地理解python变量是如何工作的:

在Python中,为什么函数可以修改调用者感知到的一些参数,而不能修改其他参数?

Python是按值调用还是按引用调用?既不。

Python是按值传递还是按引用传递?

Python是按引用传递还是按值传递?

如何通过引用传递变量?

理解Python变量和内存管理

在python中模拟值传递行为

Python函数通过引用调用

像Pythonista一样编写代码:地道的Python

除了这里的其他优秀答案之外,++和——也因未定义的行为而臭名昭著。例如,这段代码中发生了什么?

foo[bar] = bar++;

它看起来很无辜,但它是错误的C(和c++),因为您不知道第一个栏是否会增加。一个编译器可能会以一种方式执行,另一个可能会以另一种方式执行,而第三个编译器可能会让恶魔从你的鼻子里飞出来。所有这些都完全符合C和c++标准。

(编辑:c++ 17改变了给定代码的行为,这样它就被定义了;它将等价于foo[bar+1] = bar;+ +酒吧;——尽管如此,这可能不是程序员所期望的。)

在C和c++中,未定义行为被视为不可避免的邪恶,但在Python中,它只是邪恶,并尽可能避免。