我今天发现了一件奇怪的事情,并想知道是否有人可以了解这里的差异是什么?
import numpy as np
A = np.arange(12).reshape(4,3)
for a in A:
a = a + 1
B = np.arange(12).reshape(4,3)
for b in B:
b += 1
Run Code Online (Sandbox Code Playgroud)
运行每个for循环后,A没有更改,但B已经添加了一个元素.我实际上使用该B版本写入for循环内的初始化NumPy数组.
我需要知道python中的+ =做了什么.就这么简单.我也很感激链接到python中其他简写工具的定义.
看起来在Python中,list += x适用于任何可迭代的x:
In [6]: l = []
In [7]: l += [1]
In [8]: l += (2, 3)
In [9]: l += xrange(5)
In [10]: l
Out[10]: [1, 2, 3, 0, 1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
这种行为记录在哪里吗?
考虑以下代码:
>>> x = y = [1, 2, 3, 4]
>>> x += [4]
>>> x
[1, 2, 3, 4, 4]
>>> y
[1, 2, 3, 4, 4]
Run Code Online (Sandbox Code Playgroud)
然后考虑这个:
>>> x = y = [1, 2, 3, 4]
>>> x = x + [4]
>>> x
[1, 2, 3, 4, 4]
>>> y
[1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
为什么这两个有区别?
(是的,我试着寻找这个).
我对修改元组成员有点困惑.以下不起作用:
>>> thing = (['a'],)
>>> thing[0] = ['b']
TypeError: 'tuple' object does not support item assignment
>>> thing
(['a'],)
Run Code Online (Sandbox Code Playgroud)
但这确实有效:
>>> thing[0][0] = 'b'
>>> thing
(['b'],)
Run Code Online (Sandbox Code Playgroud)
还有效:
>>> thing[0].append('c')
>>> thing
(['b', 'c'],)
Run Code Online (Sandbox Code Playgroud)
不起作用,并且有效(嗯?!):
>>> thing[0] += 'd'
TypeError: 'tuple' object does not support item assignment
>>> thing
(['b', 'c', 'd'],)
Run Code Online (Sandbox Code Playgroud)
看似与以前相同,但有效:
>>> e = thing[0]
>>> e += 'e'
>>> thing
(['b', 'c', 'd', 'e'],)
Run Code Online (Sandbox Code Playgroud)
那么,当你能够并且不能修改元组内的某些内容时,游戏的规则到底是什么?它似乎更像禁止使用赋值成员的赋值运算符,但最后两个案例让我感到困惑.
Python不支持向列表添加元组:
>>> [1,2,3] + (4,5,6)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
Run Code Online (Sandbox Code Playgroud)
在语言中提供这种支持有哪些缺点?请注意,我希望这是对称的:[1, 2] + (3, 4)并且(1, 2) + [3, 4]都会评估到一个全新的列表[1, 2, 3, 4].我的理由是,一旦有人将operator +应用于元组和列表的混合,他们很可能会再次(很可能在同一个表达式中),所以我们不妨提供列表以避免额外的转换.
这是我对这个问题的动机.
经常发生的事情是我有一些小集合,我更喜欢将它们存储为元组以避免意外修改并帮助提高性能.然后我需要将这些元组与列表组合在一起,并且必须将它们中的每一个转换为列表才能生成非常难看的代码.
请注意,+=或者extend可以在简单的情况下工作.但总的来说,当我有表达时
columns = default_columns + columns_from_user + calculated_columns
Run Code Online (Sandbox Code Playgroud)
我不知道哪些是元组,哪些是列表.所以我要么必须将所有内容转换为列表:
columns = list(default_columns) + list(columns_from_user) + list(calculated_columns)
Run Code Online (Sandbox Code Playgroud)
或者使用itertools:
columns = list(itertools.chain(default_columns, columns_from_user, calculated_columns))
Run Code Online (Sandbox Code Playgroud)
这两种解决方案都比简单的总和更为丑陋; 并且chain也可能更慢(因为它必须一次遍历输入一个元素).