【问题标题】:Why does a loop or list comprehension work to initialize an array, but individually initializing the elements does not?为什么循环或列表解析可以初始化数组,但单独初始化元素却不行?
【发布时间】:2021-10-20 14:08:09
【问题描述】:

为什么初始化数组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) vs. (b)?

【问题讨论】:

  • 好吧,您必须查看列表理解是如何实现的。在引擎盖下它可能附加到数组或其他东西,不确定。您的 b) 不起作用,因为您试图访问数组中不存在的元素。如果您想要与 a) 中相同的效果,则必须使用 append 或一些等效功能

标签: python arrays list-comprehension array-initialization


【解决方案1】:

首先,如果您稍后重新绑定变量,则声明变量是没有意义的:

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

【讨论】:

    【解决方案2】:

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

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


    让我们看一下文档:

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

    列表推导式由包含表达式的括号组成,后跟一个 for 子句,然后是零个或多个 for 或 if 子句。结果将是一个新列表,该列表是在其后面的 for 和 if 子句的上下文中评估表达式而产生的。例如,如果两个列表的元素不相等,则此 listcomp 会合并它们:

    >>> [(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)]
    

    相当于:

    >>> 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]) 列表。

    【讨论】:

      【解决方案3】:

      我不明白 (a) 如何“提前”预分配数组维度。

      它没有。这个:

      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);
      

      输出是

      真的 错误的

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

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

      输出[0, 0]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-28
        • 1970-01-01
        • 2016-12-18
        • 2012-05-17
        • 2019-07-22
        • 2011-08-09
        • 1970-01-01
        • 2020-12-17
        相关资源
        最近更新 更多