【问题标题】:Assigning elements to a lists within a list将元素分配给列表中的列表
【发布时间】:2019-01-14 09:56:21
【问题描述】:

我正在运行 Python3.6,并且正在处理其中包含其他列表的列表。

list_array = [[1,0,1,0,2,2],
              [1,1,2,0,1,2],
              [2,2,2,1,0,1]]

我想修改名为 list_array 的列表,删除子列表中所有值为 2 的条目。

我使用的代码是

for k in list_array:
    k = [x for x in k if x!=2]

但是,此代码不会修改 list_array。

为什么不能以这种方式替换 list_array 中列表中的元素?

【问题讨论】:

  • 您明确地创建了一个 new 列表对象,而不是修改 list_array 引用的对象。
  • list_array = [[j for j in i if j !=2] for i in list_array] ?

标签: python python-3.x list loops iterable


【解决方案1】:

您正在创建一个新列表,而不是分配给旧列表。您可以通过使用k[:] = 添加分配来解决此问题,如下所示:

for k in list_array:
    k[:] = [x for x in k if x!=2]

【讨论】:

  • 不错的@Jonas 指出 :)
  • NB 即使有另一个变量引用,例如list_array[0],这个答案也有效。这个其他变量也会看到任何变化。
  • 谢谢@jonas。有两种方法可以从子列表中删除值为 2 的条目。第一个是 Jonas 建议的方法,另一个使用列表推导; list_array = [[x for x in sublist if x != 2] for sublist in list_array]哪种方法更快,能告诉我为什么吗?
  • @Isaac 两者的速度相同。 Jonas 在 list_array 上进行迭代,然后在 k 上进行迭代。是 O(n²)。列表理解做同样的事情。基本上,列表推导是一种在单行中执行循环的方法。
【解决方案2】:

您的代码每次都会创建一个新列表,并删除之前的列表。

在最后一次迭代中你应该得到这个:

k = [1, 0, 1]

相反,列表推导可以正常工作:

list_array = [[x for x in sublist if x != 2] for sublist in list_array]

输出:

[[1, 0, 1, 0], [1, 1, 0, 1], [1, 0, 1]]

如果你想用一个显式的 for 循环来写,可以这样写:

new_list_array = list()
for sublist in list_array:
    new_list_array.append([x for x in sublist if x != 2])

【讨论】:

  • 注意。列表推导创建一个全新的列表。现有列表可能仍然存在,但未修改。
  • @quamrana True,因此重新定义 list_array 以用新列表替换初始列表。希望那些 2 NB 的 OP 会很清楚。
【解决方案3】:

你不是在修改旧列表,你可以像那样修改它

list_array = [[1,0,1,0,2,2],[1,1,2,0,1,2],[2,2,2,1,0,1]]
for k in list_array:
   k[:]= [x for x in k if x!=2] 


print(list_array)

【讨论】:

  • 我会说它效率很低。你有一个 O(n) for 循环和一个 O(n) 索引。总的来说,对于可以在 O(n) 中实现的非常简单的事情来说,它是 O(n²)。 (不计算子列表检查和2次删除)。
猜你喜欢
  • 1970-01-01
  • 2020-06-09
  • 2012-01-05
  • 2023-03-16
  • 2019-08-31
  • 1970-01-01
  • 2020-06-22
  • 2020-09-30
  • 2020-05-06
相关资源
最近更新 更多