为什么列表函数和列表文字的行为不同?
我试图创建一个包含n 个空列表的列表,但遇到了一个有趣的情况。
首先我尝试了以下方法:
>>> n = 3
>>> list([]) * n
[]
它创建一个空列表。
之后,我尝试了以下行,它也创建了一个空列表:
>>> list(list()) * n
[]
但是当我用文字尝试同样的方法时,
>>> [[]] * n
[[], [], []]
它给出了正确的输出。有人可以解释为什么吗?
回答
list(...)不能与 互换[...]。您可以用方括号将事物包裹起来以获得嵌套列表,但将事物包裹起来list()并没有相同的效果。
-
当您编写时,
[[]]您会得到一个包含单个元素的列表。该元素是[]。 -
当你写
list([])的list构造函数采用迭代,并创建了相同元素的列表。如果你写list(['foo', 'bar'])的结果将是['foo', 'bar']. 写作list([])收益[]。当您传递不是列表的可迭代对象时,这种形式更有用。其他例子:
list('abc') == ['a', 'b', 'c'] # strings are iterables over their characters list(('foo', 'bar')) == ['foo', 'bar'] # tuple list({'foo', 'bar'}) == ['foo', 'bar'] # set; could get ['bar', 'foo'] instead -
list(list())相当于list([])。我们已经看到,这又等价于[].
[[]] * n在创建多维列表时远离。它将创建一个n引用相同列表对象的列表,并在您尝试修改内部列表时咬住您。这是每个人都会犯的常见错误。改用它,它将为每个插槽创建一个单独的空列表:
[[] for i in range(n)]
进一步阅读:
- 如何创建多维列表
- 意外反映在子列表中的列表更改列表