创建动态大小的数组的更简洁的方法

2024-05-18 17:42:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我读过python将所有变量赋值都视为引用而不是复制。所以下面生成3个独立列表的代码不起作用:

sizeNeeded = 4
itemDateNums = itemWeights = itemVolumes = [[]] * sizeNeeded

itemDateNums[1].append("hello world")
# All instances are now hello world because of referencing

所以我重写了代码:

sizeNeeded = 4
itemDateNums = []
itemWeights = []
itemVolumes = []

for shifts in range(sizeNeeded):
    itemDateNums.append([])
    itemWeights.append([])
    itemVolumes.append([])

itemDateNums[1].append("hello world")

但是语法看起来很多余。有没有一种更简洁的方式来表示需要一个拷贝赋值而不是引用赋值?你知道吗


Tags: instances代码hello列表worldallnoware
3条回答

请注意,您的代码有两个问题:

  • 正如您所注意到的,x = y = z = [some list]相同的对象分配给每个变量。对于不可变对象(如数字或字符串),这是可以的,但对于列表则不行。你知道吗
  • 而且,[[]] * number并没有达到您期望的效果,因为生成的列表将有number引用相同的空列表,即当您附加到一个列表时,您将附加到所有列表!你知道吗

相反,您可以尝试以下操作,使用列表理解来创建(双重嵌套)列表和元组解包,将其“分发”到变量:

>>> itemDateNums, itemWeights, itemVolumes = [[[] for _ in range(sizeNeeded)] for _ in range(3)]
>>> itemDateNums[1].append("hello world")
>>> itemDateNums
[[], ['hello world'], [], []]
>>> itemWeights
[[], [], [], []]

当然,这是否更干净是另一个问题。嗯,你应该把它分成三行。代码复制并不是那么糟糕,这样就可以立即清楚地知道代码的作用。你知道吗

[[]] * sizeNeeded存在对同一个内部元素进行多个引用的问题(不管您对同一个外部列表进行了多少次引用)。列表理解没有同样的问题:

itemDateNums = [ [] for i in range( sizeNeeded ) ]
itemWeights  = [ [] for i in range( sizeNeeded ) ]
itemVolumes  = [ [] for i in range( sizeNeeded ) ]

或者,冒着被弄糊涂的风险,你可以在一个作业中完成:

itemDateNums, itemWeights, itemVolumes = zip( *[ ([],[],[]) for i in range( sizeNeeded )  ] )

正如上面两位炼金术士所说的,没有什么东西需要预先初始化一个大小,但是如果你知道你的数组将是什么大小的话,效率通常是需要的。你知道吗

查看generic copy模块

>>from copy import copy as cp
>>a = [[] for _ in range(4)]
>>a
a = [[],[],[],[]]
>>b = cp(a)
>>a[1] = 4
>>a
a = [[],4,[],[]]
b = [[],[],[],[]]

但你仍然需要三行字:

itemDateNums = [[] for _ in range(sizeNeeded)]
itemWeights = cp(itemDateNums)
itemVolumes = cp(itemVolumes)

如果你真的想的话,也可以买两个,但它不那么漂亮:

itemDateNums = [[] for _ in range(sizeNeeded)]
itemWeights, itemVolumes = cp(itemDateNums), cp(itemDateNums)

我不确定有没有更干净的方法来实现这一点,使用标准库,而不安装NumPy或类似的。但如果我发现了我会更新的。你知道吗

编辑:还可以查看copy.deepcopyWhat exactly is the difference between shallow copy, deepcopy and normal assignment operation?

另外,正如托比亚斯5在下面提到的,a = [[]]*4是不安全的:

>>a = [[]]*4
>>b = [[] for _ in range(4)]
>>a[0].append(5)
>>b[0].append(5)
>>print ('a:{}\nb:{}'.format(a,b))
a: [[5], [5], [5] ,[5]]
b: [[5], [], [], []]

相关问题 更多 >

    热门问题