创建重复 N 次的可变项目列表
Creating a list of mutable items repeated N times
我有一个包含一组 x
可变项的列表。我想创建另一个列表,其中 x
组可变项重复 n
次。但是,这些项目必须是对唯一对象的引用,而不是简单地对原始对象的引用。
例如,设a = [[1],[2],[3]]
。假设我希望里面的数字重复 n=3
次,即 [[0],[2],[3],[1],[2],[3],[1],[2],[3]]
.
我可以使用 a * 3
轻松做到这一点。问题是,如果我更改 a[0][0] = 0
,那么我将得到 a == [[0],[2],[3],[0],[2],[3],[0],[2],[3]]
,这是不可取的,因为我只想更改第一个元素。还有其他方法可以实现吗?
就这样:
n = [sub_a.copy() for sub_a in a] * 3
你需要 copy()
来避免这个问题。
a = [[1],[2],[3]]
n = [sub_a.copy() for sub_a in a] * 3
a[0] = [-1]
a[2][0] = -1
print (n)
输出:
[[1], [2], [3], [1], [2], [3], [1], [2], [3]]
我刚刚发现我可以通过以下方式做到这一点:
from copy import deepcopy
a = [[1],[2],[3]]
n = 3
b = [deepcopy(val) for _ in range(n) for val in a]
现在如果我设置 b[0][0] = 0
,我将得到 b == [[0],[2],[3],[1],[2],[3],[1],[2],[3]]
。
itertools
有一个名为 repeat
. Just pair it with chain
的方法。
from itertools import repeat, chain
a = [1,2,3]
b = list(chain(*repeat(a, 3)))
>>> b
[1,2,3,1,2,3,1,2,3]
a = [1,2,3]
a = a*3
a[0] =0
print(a)
要获取可变对象的新实例,您可以将对象类型的 copy() 方法映射到相乘列表:
a = [{1},{2},{3}]
b = [*map(set.copy,a*3)]
a[0].add(7)
b[0].add(8)
b[3].add(9)
print(a) # [{1, 7}, {2}, {3}]
print(b) # [{8, 1}, {2}, {3}, {1, 9}, {2}, {3}, {1}, {2}, {3}]
如果你不知道项目的类型,或者它们有不同的类型,你可以在列表理解中做到:
b = [ i.copy() for i in a*3 ]
如果不是所有的项目都是可变的,你可以这样做:
b = [type(i)(i) for i in a*3]
如果有些可以None ...
b = [i if i is None else type(i)(i) for i in a*3]
您还可以使用涵盖所有这些情况的 deepcopy,包括包含嵌套对象的对象...
from copy import deepcopy
b = [*map(deepcopy,a*3)]
非常简单,您需要复制 a
,而不是重复引用原始的可变对象。如果你只需要一层复制,你可以这样做,注意它是一个 shallow 复制(见第二个输出)。
a = [[1, 1], [2], [3, 3, 3]]
b = a[:] * 3
b[0] = "change"
print(b)
b[2][1] = "deep"
print(b)
输出:
['change', [2], [3, 3, 3], [1, 1], [2], [3, 3, 3], [1, 1], [2], [3, 3, 3]]
['change', [2], [3, 'deep', 3], [1, 1], [2], [3, 'deep', 3], [1, 1], [2], [3, 'deep', 3]]
看看如何只给第一层一个新的参考。当您尝试更改更深的元素时,您会发现嵌套列表仍然是同一个对象。要修复 那个 问题,请对 b
的每个元素使用深拷贝:
import copy
a = [[1, 1], [2], [3, 3, 3]]
b = [copy.deepcopy(a) for _ in range(3)]
b[0] = "change"
print(b)
b[2][1] = "deep"
print(b)
输出:
['change', [[1, 1], [2], [3, 3, 3]], [[1, 1], [2], [3, 3, 3]]]
['change', [[1, 1], [2], [3, 3, 3]], [[1, 1], 'deep', [3, 3, 3]]]
我有一个包含一组 x
可变项的列表。我想创建另一个列表,其中 x
组可变项重复 n
次。但是,这些项目必须是对唯一对象的引用,而不是简单地对原始对象的引用。
例如,设a = [[1],[2],[3]]
。假设我希望里面的数字重复 n=3
次,即 [[0],[2],[3],[1],[2],[3],[1],[2],[3]]
.
我可以使用 a * 3
轻松做到这一点。问题是,如果我更改 a[0][0] = 0
,那么我将得到 a == [[0],[2],[3],[0],[2],[3],[0],[2],[3]]
,这是不可取的,因为我只想更改第一个元素。还有其他方法可以实现吗?
就这样:
n = [sub_a.copy() for sub_a in a] * 3
你需要 copy()
来避免这个问题。
a = [[1],[2],[3]]
n = [sub_a.copy() for sub_a in a] * 3
a[0] = [-1]
a[2][0] = -1
print (n)
输出:
[[1], [2], [3], [1], [2], [3], [1], [2], [3]]
我刚刚发现我可以通过以下方式做到这一点:
from copy import deepcopy
a = [[1],[2],[3]]
n = 3
b = [deepcopy(val) for _ in range(n) for val in a]
现在如果我设置 b[0][0] = 0
,我将得到 b == [[0],[2],[3],[1],[2],[3],[1],[2],[3]]
。
itertools
有一个名为 repeat
. Just pair it with chain
的方法。
from itertools import repeat, chain
a = [1,2,3]
b = list(chain(*repeat(a, 3)))
>>> b
[1,2,3,1,2,3,1,2,3]
a = [1,2,3]
a = a*3
a[0] =0
print(a)
要获取可变对象的新实例,您可以将对象类型的 copy() 方法映射到相乘列表:
a = [{1},{2},{3}]
b = [*map(set.copy,a*3)]
a[0].add(7)
b[0].add(8)
b[3].add(9)
print(a) # [{1, 7}, {2}, {3}]
print(b) # [{8, 1}, {2}, {3}, {1, 9}, {2}, {3}, {1}, {2}, {3}]
如果你不知道项目的类型,或者它们有不同的类型,你可以在列表理解中做到:
b = [ i.copy() for i in a*3 ]
如果不是所有的项目都是可变的,你可以这样做:
b = [type(i)(i) for i in a*3]
如果有些可以None ...
b = [i if i is None else type(i)(i) for i in a*3]
您还可以使用涵盖所有这些情况的 deepcopy,包括包含嵌套对象的对象...
from copy import deepcopy
b = [*map(deepcopy,a*3)]
非常简单,您需要复制 a
,而不是重复引用原始的可变对象。如果你只需要一层复制,你可以这样做,注意它是一个 shallow 复制(见第二个输出)。
a = [[1, 1], [2], [3, 3, 3]]
b = a[:] * 3
b[0] = "change"
print(b)
b[2][1] = "deep"
print(b)
输出:
['change', [2], [3, 3, 3], [1, 1], [2], [3, 3, 3], [1, 1], [2], [3, 3, 3]]
['change', [2], [3, 'deep', 3], [1, 1], [2], [3, 'deep', 3], [1, 1], [2], [3, 'deep', 3]]
看看如何只给第一层一个新的参考。当您尝试更改更深的元素时,您会发现嵌套列表仍然是同一个对象。要修复 那个 问题,请对 b
的每个元素使用深拷贝:
import copy
a = [[1, 1], [2], [3, 3, 3]]
b = [copy.deepcopy(a) for _ in range(3)]
b[0] = "change"
print(b)
b[2][1] = "deep"
print(b)
输出:
['change', [[1, 1], [2], [3, 3, 3]], [[1, 1], [2], [3, 3, 3]]]
['change', [[1, 1], [2], [3, 3, 3]], [[1, 1], 'deep', [3, 3, 3]]]