如题,为何结果是[0,0,0,0,0,0,0,0,0]
1
SakuraSa 2017-04-28 11:10:53 +08:00 1
list * int 意思是将数组重复 int 次并依次连接形成一个新数组
|
2
guyskk 2017-04-28 11:14:19 +08:00 1
提醒一下有个坑:
>>> items = [{}] * 10 >>> items[0]['key'] = 'value' >>> print(items) |
4
xiadd 2017-04-28 11:21:30 +08:00
@guyskk 感觉不是坑 是很正常的对象引用 原对象变化了 引用的对象自然发生了变化 js 里这种情况才是常态 当然我 python 不是很熟
|
5
guyskk 2017-04-28 11:30:33 +08:00
@xiadd #4
有一次我这样初始化一个列表: items = [{} for i in range(10)] 然后发现貌似可以这样写: items = [{}] * 10 结果出现很诡异的 Bug,印象深刻 |
6
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 这个默认参数是会改变的,因为默认参数的值也是对该数组的引用 |
8
NoAnyLove 2017-04-28 13:25:09 +08:00 2
相当于初始化一个长度为 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 》中有详细讲解,看完之后有种恍然大悟的感觉。。。。。。然而我还没看完。。。。。。貌似最近中文翻译版也要发布了 |
9
KIDJourney 2017-04-28 13:47:07 +08:00
@guyskk 这个主要是 mutable 复制时的问题吧。
|
10
guyskk 2017-04-28 14:01:59 +08:00
@KIDJourney #9 这里不是复制,list 里面的元素都是同一个对象。mutable 对象复制应该是 copy 和 deepcopy 的问题。
|