Create a list utilizing multiplication but not have each list mirror

人盡茶涼 提交于 2019-12-11 06:10:01

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!