为什么循环或列表理解可以初始化数组,但单独初始化元素却不行?

Why does a loop or list comprehension work to initialize an array, but individually initializing the elements does not?

为什么初始化数组 arr 在作为列表理解完成时有效(我认为这是以下示例的内容 -- 不确定),但在每个数组位置单独初始化时却无效?

例如,这有效: (一)

arr=[] 
arr=[0 for i in range(5)]

但是 (b),

arr=[]
arr[0]=0
arr[1]=0

等等,没有。

arr=[0 for i in range(5)]指令本质上不就是一下子完成了上面(b)中所做的事情吗?

我意识到需要预定义(或分配)数组大小。所以,我可以理解

arr= [0]*5

或使用 numpy,

arr = np.empty(10, dtype=object)

工作。 但是,我看不到 (a) 如何“提前”预分配数组维度。 python 如何解释上面的 (a) 与 (b)?

首先,如果您稍后重新绑定变量,则声明变量毫无意义:

arr = []  # <-- this line is entirely pointless
arr = [0 for i in range(5)]

其次,两个表达式

[0 for i in range(5)]
[0] * 5

创建一个新的list对象,而

arr[0] = 0

改变一个已有的,即它想重新赋值arr的第一个元素。由于这不存在,您将看到一个错误。你可以这样做:

arr = []
arr.append(0)
arr.append(0)

逐步填充最初为空的 list

请注意,Python 列表不是 Array,比方说,Java 认为它具有预定义的大小。它更像是一个 ArrayList.

它不预先分配。它基本上只是在一个循环中追加,形式很好(语法糖)。

为什么不预先分配?因为要预分配,我们需要知道可迭代对象的长度,它可能是一个生成器,它会用完它。而且,理解可以有一个 if 子句,限制最终进入列表的内容。 (另请参阅生成器理解,它创建生成器 - 没有预分配,因为它是惰性评估的)


我们来看看文档:

https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions

A list comprehension consists of brackets containing an expression followed by a for clause, then zero or more for or if clauses. The result will be a new list resulting from evaluating the expression in the context of the for and if clauses which follow it. For example, this listcomp combines the elements of two lists if they are not equal:

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

and it’s equivalent to:

>>> combs = []
>>> for x in [1,2,3]:
...     for y in [3,1,4]:
...         if x != y:
...             combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

看到了吗?相当于附加,而不是预分配 (n*[0]) 列表。

I don't see how (a) preallocates the array dimension "ahead of time".

没有。这个:

arr=[] 
arr=[0 for i in range(5)]

创建一个空数组(我认为它更准确地称为 list 但我不是一个强大的 Python 人)并将其存储在 arr,然后创建一个全新的无关数组并将新数组放入 arr,丢弃旧数组。它不会初始化您使用 arr=[] 创建的数组。您可以完全删除第一行 (arr=[]);它没有做任何有用的事情。

你可以看到它们是这样的不同数组:

# Create a blank array, store it in `a`
a = []
# Store that same array in `b`
b = a
# Show that they're the same array
print(a == b);
# Create a new array and put it in `a`
a = [0 for i in range(5)]
# Show that they aren't the same array
print(a == b);

输出为

True
False

所以只需使用 arr=[0 for i in range(5)] 或者,如果您想单独使用,请使用 append:

a = []
a.append(0)
a.append(0)
print(a)

输出 [0, 0].