问题
Quick question, hope you guys can help:
Here is my code:
def nd_mkboard(dims, filler):
n = len(dims)
helpboard = [filler]
helpboard = helpboard * dims[n-1]
for i in reversed(range(n)):
if i != 1:
helpboard = [helpboard] * dims[i-1]
return helpboard
ex.:
stuff = nd_mkboard([2, 4, 2], False)
print(stuff)
[[[False, False], [False, False], [False, False], [False, False]],
[[False, False], [False, False], [False, False], [False, False]]]
stuff[0][0][0] = True
print(stuff)
[[[True, False], [True, False], [True, False], [True, False]],
[[True, False], [True, False], [True, False], [True, False]]]
How do I avoid this linkage problem? All I want is:
[[[True, False], [False, False], [False, False], [False, False]],
[[False, False], [False, False], [False, False], [False, False]]]
回答1:
See this question.
Lists are references. So copying a list is copying references, which means you wind up pointing to the same thing.
Multiplying a list is making multiple copies, as above.
To get around this problem, use the list[:]
slice notation to clone the list, or structure your code to create new lists each iteration.
You're pretty much doomed as far as making copies goes, since that's what you want to avoid. You could use copy.deepcopy, but you might be better off just writing a recursive function.
Update:
Here's a function that recursively builds the structure, and can handle constructed objects as well.
def make_structure(dim1, *args, fill=None):
fill = False if fill is None else fill
get_fill = lambda: fill() if callable(fill) else fill
result = []
for i in range(dim1):
if len(args):
result.append(make_structure(*args, fill=fill))
else:
result.append(get_fill())
return result
lines = [2,4,2]
s = make_structure(2,4,2)
print(s)
s[0][0][0] = True
print(s)
class TestObj:
def __init__(self):
self.id = id(self)
def __repr__(self):
return str(self.id)
s = make_structure(2,4,2,fill=TestObj)
print(s)
s[0][2][1] = TestObj()
print(s)
Update 2:
List instead of args:
def make_structure(dims, fill=None):
fill = False if fill is None else fill
get_fill = lambda: fill() if callable(fill) else fill
result = []
for i in range(dims[0]):
if len(dims) > 1:
result.append(make_structure(dims[1:], fill=fill))
else:
result.append(get_fill())
return result
来源:https://stackoverflow.com/questions/42631412/create-a-list-utilizing-multiplication-but-not-have-each-list-mirror