Python:如何用我可以附加到的空值初始化嵌套列表
Python: How to initialize a nested list with empty values which i can append to
我正在学习 python 但碰壁了。
我正在尝试定义一个二维列表,稍后我可以使用它来附加值。这对应于 width *height
的网格
我尝试使用 [] 来初始化空列表,但是 wid 被忽略了。
我尝试使用 None 作为占位符,但我无法附加
wid = 3
hgt = 3
l1 = [[]*wid ] * hgt
l = [[None]*wid ] * hgt
l[1][1].append("something")
结果
l1: [[], [], []]
l: [[None, None, None], [None, None, None], [None, None, None]]
错误:
append: AttributeError: 'NoneType' object has no attribute 'append'
想要的结果:[[[], [], []], [[], [], []], [[], [], []]]
有两种方法
- 使用
None
作为占位符值,将其替换为l[1][1] = 5
- 使用空列表并追加新元素,
l[1].append(5)
目前,您正在混合使用这两种方式。 l[1][1]
returns 一个 None
值, 不是一个列表,而您正在尝试对其调用 append
。
无论如何,这里有一个常见的 python 陷阱。当你写
mylist = [[None]*2]*3
这有两个作用
- 创建列表
[None, None]
- 使用此列表 3 次以创建另一个列表
关键是外部列表将包含内部列表的 3 个 副本 ,而不是 3 个不同的相同列表。所以,每次你修改其中一个,其余的也会被修改。因此,您需要复制内部列表。
然而,对于二维数组,最好的方法是使用 numpy
x = np.zeros(m, n)
x[1, 2] = 5
尝试在列表推导中使用列表推导:
>>> [ [ [] for i in range(wid) ] for i in range(hgt) ]
[[[], [], []], [[], [], []], [[], [], []]]
请注意,这比列表乘法更可取,因为每个列表都是唯一的。比较:
>>> x = [ [[] for i in range(wid)] for i in range(hgt) ]
>>> x[1][1].append('a')
>>> x
[[[], [], []], [[], ['a'], []], [[], [], []]]
对比
>>> y = [ [[]] * wid for i in range(hgt) ]
>>> y[1][1].append('a')
>>> y
[[[], [], []], [['a'], ['a'], ['a']], [[], [], []]]
对比
>>> z = [ [[]] * wid ] * hgt
>>> z[1][1].append('a')
>>> z
[[['a'], ['a'], ['a']], [['a'], ['a'], ['a']], [['a'], ['a'], ['a']]]
其中,在第二种和第三种情况下,'a'出现在多个单元格中!而使用 None
并不能避免这个问题:
>>> m = [ [None] * wid ] * hgt
>>> m
[[None, None, None], [None, None, None], [None, None, None]]
>>> if m[1][1] is None:
... m[1][1] = ['a']
... else:
... m[1][1].append('a')
...
>>> m
[[None, ['a'], None], [None, ['a'], None], [None, ['a'], None]]
tl;dr - 使用双列表理解。在我看来,无论如何,它是最易读的选项。
>>> x = 5
>>> y = 5
>>> [[None for _ in range(x)] for _ in range(y)]
[[None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None]]
不要使用 [[None]*x]*y
除非你真的知道你刚刚创建了共享引用。
如果你正在处理矩阵,你可以使用 numpy:
import numpy as np
my_matrix = np.zeros((rows, columns) # with 2 dimentions
我正在学习 python 但碰壁了。 我正在尝试定义一个二维列表,稍后我可以使用它来附加值。这对应于 width *height
的网格我尝试使用 [] 来初始化空列表,但是 wid 被忽略了。 我尝试使用 None 作为占位符,但我无法附加
wid = 3
hgt = 3
l1 = [[]*wid ] * hgt
l = [[None]*wid ] * hgt
l[1][1].append("something")
结果
l1: [[], [], []]
l: [[None, None, None], [None, None, None], [None, None, None]]
错误:
append: AttributeError: 'NoneType' object has no attribute 'append'
想要的结果:[[[], [], []], [[], [], []], [[], [], []]]
有两种方法
- 使用
None
作为占位符值,将其替换为l[1][1] = 5
- 使用空列表并追加新元素,
l[1].append(5)
目前,您正在混合使用这两种方式。 l[1][1]
returns 一个 None
值, 不是一个列表,而您正在尝试对其调用 append
。
无论如何,这里有一个常见的 python 陷阱。当你写
mylist = [[None]*2]*3
这有两个作用
- 创建列表
[None, None]
- 使用此列表 3 次以创建另一个列表
关键是外部列表将包含内部列表的 3 个 副本 ,而不是 3 个不同的相同列表。所以,每次你修改其中一个,其余的也会被修改。因此,您需要复制内部列表。
然而,对于二维数组,最好的方法是使用 numpy
x = np.zeros(m, n)
x[1, 2] = 5
尝试在列表推导中使用列表推导:
>>> [ [ [] for i in range(wid) ] for i in range(hgt) ]
[[[], [], []], [[], [], []], [[], [], []]]
请注意,这比列表乘法更可取,因为每个列表都是唯一的。比较:
>>> x = [ [[] for i in range(wid)] for i in range(hgt) ]
>>> x[1][1].append('a')
>>> x
[[[], [], []], [[], ['a'], []], [[], [], []]]
对比
>>> y = [ [[]] * wid for i in range(hgt) ]
>>> y[1][1].append('a')
>>> y
[[[], [], []], [['a'], ['a'], ['a']], [[], [], []]]
对比
>>> z = [ [[]] * wid ] * hgt
>>> z[1][1].append('a')
>>> z
[[['a'], ['a'], ['a']], [['a'], ['a'], ['a']], [['a'], ['a'], ['a']]]
其中,在第二种和第三种情况下,'a'出现在多个单元格中!而使用 None
并不能避免这个问题:
>>> m = [ [None] * wid ] * hgt
>>> m
[[None, None, None], [None, None, None], [None, None, None]]
>>> if m[1][1] is None:
... m[1][1] = ['a']
... else:
... m[1][1].append('a')
...
>>> m
[[None, ['a'], None], [None, ['a'], None], [None, ['a'], None]]
tl;dr - 使用双列表理解。在我看来,无论如何,它是最易读的选项。
>>> x = 5
>>> y = 5
>>> [[None for _ in range(x)] for _ in range(y)]
[[None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None]]
不要使用 [[None]*x]*y
除非你真的知道你刚刚创建了共享引用。
如果你正在处理矩阵,你可以使用 numpy:
import numpy as np
my_matrix = np.zeros((rows, columns) # with 2 dimentions