首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >2d python列表流行

2d python列表流行
EN

Stack Overflow用户
提问于 2020-03-14 13:20:37
回答 2查看 32关注 0票数 0

我被python list的行为搞糊涂了。如果有人能解释一下python为什么会这样,我将不胜感激。

代码语言:javascript
复制
list = [[]]*5
list[0].append(10)
list[1].append(20)
list.append(30)

我认为输出应该是:

代码语言:javascript
复制
[ [10], [20], [], [], [], 30 ]

但我得到的输出是:

代码语言:javascript
复制
[ [10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30 ]

这会不会是因为嵌套列表只是初始列表的副本?如果是这样的话,有什么方法可以做到这一点,使它不只是复制初始列表?

EN

回答 2

Stack Overflow用户

发布于 2020-03-14 13:35:32

您希望生成嵌套列表,如下所示:

代码语言:javascript
复制
foo = [[] for x in range(5)]

如果你说:

代码语言:javascript
复制
foo[0].append(10)
foo[1].append(20)

您将会得到预期的结果:

代码语言:javascript
复制
[[10], [20], [], [], []]

任何时候进行嵌套编辑时,Python默认为基本操作的浅层副本。假设您现在想要制作一个独立的foo副本。你必须这样做:

代码语言:javascript
复制
import copy
bar = copy.deepcopy(foo)

如果不这样做,你会遇到这样的问题:

代码语言:javascript
复制
zed = foo
foo[2].append(40)
print(zed)
>>> [[10], [20], [40], [], []]

这不是问题,除非你有嵌套的列表...但对于它可能突然出现的其他地方,可以看看其他答案。

票数 1
EN

Stack Overflow用户

发布于 2020-03-14 13:51:24

我看到了一个很好的答案,但我觉得这里有一些解释是合理的,因为这是Python新手,有时是有经验的人的常见陷阱。在我的脑海中有两种可能发生这种情况的方法。一个是在列表声明中,另一个是在函数/方法声明中。

li = [[]] * 8这一行创建了一个指向同一列表的引用列表。这就是为什么当您附加到一个li[0].append(10)后,该列表会显示8个列表,其中10个是成员。解决方案是在声明中使用列表理解。li = [[] for _ in range(8)]

现在是下一个问题了。函数或方法声明。通常,我们希望参数的默认值如下:

代码语言:javascript
复制
>>> def foo(bar=[]):
...     bar.append('hello')
...     return bar
...     
>>> foo()
['hello']
>>> foo()
['hello', 'hello']
>>> foo()
['hello', 'hello', 'hello']
>>> 

使用[]作为默认值的问题是解释器在解析函数声明时,只创建一个列表实例作为默认值。因此,每次调用该函数时,都会传入相同的列表。

这也适用于字典。事实上,在函数声明中使用任何类型的可变对象实例作为参数默认值都可能导致混淆。

我认为关键是* 8应用于某些对象,比如列表创建引用,而不是实例。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60679973

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档