为什么python的行为不符合预期

时间:2015-12-09 07:14:43

标签: python

我认为这是一个非常奇怪的python代码,但我不知道原因:

<ul id="one-way">
  <li>
    <img src="https://placehold.it/200x200" alt="" />
    <span>1</span><!-- or div or p or what have you -->
  </li>
</ul>

<ul id="or-another">
  <li>
    <img src="https://placehold.it/200x200" alt="" />
    <span>2</span>
  </li>
</ul>

<ul id="one-more">
  <li>
    <span>3</span>
  </li>
</ul>

为什么In [7]: a = [[]] * 3 In [8]: b = [[], [], []] In [9]: a == b Out[9]: True In [10]: a[0].append(1) In [11]: b[0].append(1) In [12]: a == b Out[12]: False In [13]: a Out[13]: [[1], [1], [1]] In [14]: b Out[14]: [[1], [], []] 之后的[[1], [1], [1]]是?

类似的问题是:

a[0].append(1)

据我了解,In [15]: c = dict.fromkeys(range(3),[]) In [16]: d = {0:[], 1:[], 2:[]} In [17]: c == d Out[17]: True In [18]: c[0].append(1) In [19]: d[0].append(1) In [20]: c == d Out[20]: False In [21]: c Out[21]: {0: [1], 1: [1], 2: [1]} In [22]: d Out[22]: {0: [1], 1: [], 2: []} ab也等于c,但事实并非如此。为什么?谁能帮我?非常感谢!

4 个答案:

答案 0 :(得分:4)

第一个版本:

>>> a = [[]] * 3

创建一个包含相同列表三倍的列表。查看元素的ID:

>>> [id(x) for x in a]
[4454962120, 4454962120, 4454962120]

虽然这个:

>>> b = [[], [], []]

创建三个不同的列表:

>>> [id(x) for x in b]
>>> [4454963720, 4455011592, 4454853448]

您可以使用列表推导创建包含不同子列表的大型列表:

>>> size = 100
>>> long_list = [[] for x in range(size)]

现在附加到第一个子列表:

>>> long_list[0].append(10)
>>> long_list[:10]

仅更改第一个子列表:

>>> long_list[:10]
[[10], [], [], [], [], [], [], [], [], []]

答案 1 :(得分:2)

[[]]*3创建一个包含3个对同一列表的引用的列表,而[[],[],[]]创建3个对3个不同列表的引用的列表。

答案 2 :(得分:2)

对于ac,您将创建一个空列表,该列表被引用3次。当您更改它时,对它的所有引用都会更改。对于bd,您可以创建3个完全独立的单独空列表。

您可以使用is运算符检查两个对象是否相同,例如x is y。以下是您在第一个示例中显示的内容:

>>> a = [[]] * 3
>>> b = [[], [], []]
>>>
>>> a[0] is a[1]
True
>>> b[0] is b[1]
False
>>>

在你的第二个例子中:

>>> c = dict.fromkeys(range(3), [])
>>> d = {0:[], 1:[], 2:[]}
>>>
>>> c[0] is c[1]
True
>>> d[0] is d[1]
False
>>>

答案 3 :(得分:0)

在这两种情况下,&amp; c包含对单个空列表的3个引用,但b&amp; d包含3个空列表。所以当你比较他们3个空的== 3个空的时候。

当您附加到&amp;中的两个的第一个元素时c您附加到单个列表中,您有3个引用,因此所有3个引用[1],但在b&amp; d您附加到3个列表中的第一个列表,只有那个列表被更改。

使用相同的定义:

In [8]: a[0] is a[1]
Out[8]: True

In [9]: b[0] is b[1]
Out[9]: False