为什么一个变量被我的函数更改,而另一个变量却没有更改?

时间:2019-05-15 18:55:47

标签: python python-3.x

我在使用Python时遇到了麻烦。我定义了一个简单的函数,该函数将两个列表(都包含两个元组)作为参数。在该函数执行期间,将元组逐渐添加到addmap中,而在该函数的末尾从toberemoved中删除了一个名为removemap的列表。

两个参数都代表函数外部的列表。在函数运行后更改列表addmap时,removemap保持不变。这很奇怪,因为如果我在函数中打印出removemap,它将显示我想要的结果。我只是看不到外面。这里发生了什么?谢谢!

def loescheeinzelgaenger(removemap, addmap):
    toberemoved = [] #lists all the list values which should be removed from the removemap and added to the addmap
    for row in range(shape[0]):
        for column in range(shape[1]):
            if (row,column) in removemap:
                # define 4 neighbours
                n1 = (row - 1, column)
                n2 = (row, column - 1)
                n3 = (row + 1, column)
                n4 = (row, column + 1)
                if intersection([n1,n2,n3,n4],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
                elif intersection([n1,n2,n3],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
                elif intersection([n2,n3,n4],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
                elif intersection([n1, n3,n4],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
                elif intersection([n1,n2,n4],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
    removemap = [x for x in removemap if x not in toberemoved]
    print(removemap) #it's changed here

#further down:

print(grassMap) #initial
print(waterMap) #initial

loescheeinzelgaenger(waterMap,grassMap)

print(grassMap) #changed
print(waterMap) #unchanged

5 个答案:

答案 0 :(得分:3)

removemap = [x for x in removemap if x not in toberemoved]

此行创建一个新的本地列表,该列表与传递给该函数的列表无关。

唯一明显的解决方案是从函数中将其返回:

def loescheeinzelgaenger(removemap, addmap):
    ...    
    return [x for x in removemap if x not in toberemoved]

waterMap = loescheeinzelgaenger(waterMap, grassMap)

答案 1 :(得分:3)

您的代码明确地更改了addmap

                addmap.append((row, column))

这将追加到现有列表中。但是,您使用其他“技术”来处理本地removemap

removemap = [x for x in removemap if x not in toberemoved]

这表示要接受传入的removemap,迭代其元素,过滤出所需的元素,然后从这些元素中创建一个 new 列表。最后,将此新列表分配给局部变量removemap。由于此操作将对象引用更改为新列表,因此您不再使用从调用例程传递的引用...,并且那个 removemap变量仍指向原始列表

要更改原始列表,可以仔细使用remove方法:

for rem in toberemoved:
    while rem in removemap:
        removemap.remove(rem)

答案 2 :(得分:0)

添加return语句以获取所需的值:

def loescheeinzelgaenger(removemap, addmap):
    toberemoved = [] #lists all the list values which should be removed from the removemap and added to the addmap
    for row in range(shape[0]):
        for column in range(shape[1]):
            if (row,column) in removemap:
                # define 4 neighbours
                n1 = (row - 1, column)
                n2 = (row, column - 1)
                n3 = (row + 1, column)
                n4 = (row, column + 1)
                if intersection([n1,n2,n3,n4],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
                elif intersection([n1,n2,n3],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
                elif intersection([n2,n3,n4],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
                elif intersection([n1, n3,n4],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
                elif intersection([n1,n2,n4],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
    removemap = [x for x in removemap if x not in toberemoved]
    print(removemap) #it's changed here
    return removemap, addmap

 waterMap,grassMap = loescheeinzelgaenger(waterMap,grassMap)

您基本上是在告诉Python:在此函数中完成的所有操作中,我希望您以函数末尾的状态给我这两个变量

答案 3 :(得分:0)

其他人已经勾勒出这条线,这会导致您的行为。但是我还要重构您的代码:(您使用了全局变量shape

def loescheeinzelgaenger(removemap, number_of_rows, number_of_columns):
    toberemoved = [] #lists all the list values which should be removed from the removemap and added to the addmap
    addmap = []
    for row in range(number_of_rows):
        for column in range(number_of_columns):
            if (row,column) in removemap:
                # define 4 neighbours
                n1 = (row - 1, column)
                n2 = (row, column - 1)
                n3 = (row + 1, column)
                n4 = (row, column + 1)
                if intersection([n1,n2,n3,n4],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
                elif intersection([n1,n2,n3],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
                elif intersection([n2,n3,n4],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
                elif intersection([n1, n3,n4],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
                elif intersection([n1,n2,n4],removemap) == []:
                    toberemoved.append((row, column))
                    addmap.append((row, column))
    new_removemap = [x for x in removemap if x not in toberemoved]
    return new_removemap, addmap

waterMap, grassMap = loescheeinzelgaenger(waterMap, shape[0], shape[1])

另外要补充一点:我不会混合使用不同的语言来命名变量。

答案 4 :(得分:0)

您可以从函数中返回新创建的列表,然后将返回值分配给removemap,如其他答案中所述,也可以像这样在函数中更改列表removemap

for x in toberemoved: 
    if x in removemap:
        removemap.remove(x)

这样,您可以更改传入的实际列表,而不创建新列表。