Python [0] * n 描述的意思是?

2017-04-28 10:59:00 +08:00
 vainly

如题,为何结果是[0,0,0,0,0,0,0,0,0]

3859 次点击
所在节点    Python
11 条回复
SakuraSa
2017-04-28 11:10:53 +08:00
list * int 意思是将数组重复 int 次并依次连接形成一个新数组
guyskk
2017-04-28 11:14:19 +08:00
提醒一下有个坑:
>>> items = [{}] * 10
>>> items[0]['key'] = 'value'
>>> print(items)
vainly
2017-04-28 11:19:47 +08:00
@SakuraSa
@guyskk
谢谢两位
xiadd
2017-04-28 11:21:30 +08:00
@guyskk 感觉不是坑 是很正常的对象引用 原对象变化了 引用的对象自然发生了变化 js 里这种情况才是常态 当然我 python 不是很熟
guyskk
2017-04-28 11:30:33 +08:00
@xiadd #4
有一次我这样初始化一个列表:
items = [{} for i in range(10)]
然后发现貌似可以这样写:
items = [{}] * 10
结果出现很诡异的 Bug,印象深刻
AZLisme
2017-04-28 11:40:30 +08:00
这个很正常,Mutable 对象都是按引用传递的:
a = {}
b = a
a['1'] = 1
print(b)

跟这个是一个道理。
同理还有定义函数的时候:

def foo(bar=[]):
bar.append(1)
print(bar)
foo()
foo()

bar 这个默认参数是会改变的,因为默认参数的值也是对该数组的引用
imn1
2017-04-28 11:45:08 +08:00
@guyskk
应该这样写
items[0] = {'key':'value'}
NoAnyLove
2017-04-28 13:25:09 +08:00
相当于初始化一个长度为 n,每个元素的初始值都是 0 的`list`。貌似这是 Python 初始化 /预分配有较多元素的`list`的常用做法,貌似也是唯一的做法(有知道其他做法的朋友请分享一下)。

感觉上等同于 C++的

```
vector<int> tmp(n, 0)
```

(但其实我不了解 C++的标准库,不知道说得对不对)

正如 2L 所说,需要注意,如果要初始化的`list`中的的元素是其他 container 类型(比如`list`、`set`、`dict`等,但不包括`tuple`,`tuple`本身是不可变的,不实用于这里),因为 Python 中所有东西都是类的概念,变量其实类似于 Java/C++中的引用变量。如果要初始化一个 10*10 全是 0 的二位数组,所以如果按照

```
l = [[0] * 10] * 10
l[0][0]=1
print(l)
```

来初始化一个 2 维的`list`,你会“惊喜”地发现`l`中的每个元素都是指向同一个`list`对象。所以正确的做法是:

```
l = [[0] * 10 for _ in range(10)]
```

说到这里,真心想给《 Fluent Python 》打个广告,这个问题和之前看到的另外一个对`tuple`进行`+=`操作的问题,其实都在《 Fluent Python 》中有详细讲解,看完之后有种恍然大悟的感觉。。。。。。然而我还没看完。。。。。。貌似最近中文翻译版也要发布了
KIDJourney
2017-04-28 13:47:07 +08:00
@guyskk 这个主要是 mutable 复制时的问题吧。
guyskk
2017-04-28 14:01:59 +08:00
@KIDJourney #9 这里不是复制,list 里面的元素都是同一个对象。mutable 对象复制应该是 copy 和 deepcopy 的问题。
llb123
2017-04-28 14:44:25 +08:00
@guyskk #2 浅拷贝

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/357903

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX