【发布时间】:2016-09-11 02:52:12
【问题描述】:
我偶然发现了“x = [m]*n”并在解释器中运行它,我可以看到代码分配了一个用 m 初始化的 n 元素数组。但是我在网上找不到这种代码的描述。这叫什么?
>>> x = [0]*7
>>> x
[0, 0, 0, 0, 0, 0, 0]
【问题讨论】:
-
也适用于字符串
标签: python terminology
我偶然发现了“x = [m]*n”并在解释器中运行它,我可以看到代码分配了一个用 m 初始化的 n 元素数组。但是我在网上找不到这种代码的描述。这叫什么?
>>> x = [0]*7
>>> x
[0, 0, 0, 0, 0, 0, 0]
【问题讨论】:
标签: python terminology
* 只是一个乘法 - 因为列表的+ 是一个直观的东西,意味着连接两个操作数,下一步是乘以一个标量 - [0] * N 表示“将这个列表与自身连接 N 次” !
换句话说:* 是 Python 中为其原始序列类型定义的运算符,并且是一个整数,用于将序列与自身连接该次数。它适用于列表、元组甚至字符串。
这在 Python 中有些自然,因为该语言允许运算符重载 - 因此 Python 程序员确实希望运算符对对象做有意义的事情。
应该注意组成结果列表的对象不是原始列表中对象的副本,而是对同一对象的引用。因此,如果原始列表的内容只是数字或其他一些不可变对象,那就不足为奇了 - 但如果它包含可变对象,例如内部列表,则在更改它们时可能会受到严重的副作用 - 就像在这个sn-p:
In [167]: a = [[0]] * 7
In [168]: a
Out[168]: [[0], [0], [0], [0], [0], [0], [0]]
In [169]: a[0].append(1)
In [170]: a
Out[170]: [[0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1]]
【讨论】:
从the Python docs' description 开始,在整数n 和原始序列类型之间使用的乘法运算符* 对序列n 中的项目执行序列重复次数。所以我想你正在寻找的术语是序列重复。请注意,这不是“序列复制”,因为没有创建项目的副本 - 您有 n 对相同序列的引用。
【讨论】:
* 实际上没有为任何序列定义 - 它是为内置序列类型定义的(list tuple,ste , bytes, bytearray),但不作为 collections.abc.Sequence 的混合功能存在,“事实上”定义了“序列协议”。 (在 Python 2.x 中,只需 collections.Sequence)
collections.abc.Sequence 不能假设您的构造函数会像标准序列那样采用可迭代对象。集合也会出现同样的问题,但是省略所有集合运算符会留下一个不是集合的集合,所以他们硬着头皮在一个可以覆盖的私有方法中做出假设。