函数调用它对全局变量有副作用

2024-10-02 18:28:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在学习课程中的背包问题:https://courses.edx.org/courses/course-v1:MITx+6.00.2x+3T2019/course/

具有以下输入:

cows = {"Jesse": 6, "Maybel": 3, "Callie": 2, "Maggie": 5}

我必须返回一个列表作为输出,比如:

[['Jesse', 'Maybel'], ['Callie', 'Maggie']]

我编写的函数似乎运行良好,因为它返回正确的结果:

def greedy_cow_transport(cows,capacity):
    ocupied = 0
    current_trip = []
    all_trips = []


    while(True):
        for cow in cows:
            if ocupied+cow[1] < capacity:
                current_trip.append((cow[0])) 
                ocupied += cow[1]
                cows.remove(cow)
            else:

                all_trips.append(current_trip)
                ocupied = 0
                current_trip = []
        if len(cows)==0:
            all_trips.append(current_trip)
            break
    return all_trips

问题是在打过一次电话之后:

order = copy.copy(sorted(cows.items(), key=lambda x: x[1],reverse= True ))

greedy_cow_transport(order,capacity)

变量顺序是一个空列表。 我不明白为什么会发生这种情况,因为我只在函数的作用域内使用.remove方法。为什么这些会影响我的主要变量?你知道吗


Tags: currentallcapacitytripcourseappendtripscow
2条回答

既然您试图使用copy.copy,我假设您理解python通过参数的值传递对对象的引用。您只需要保留对排序顺序的引用。你知道吗

脚本

$ cat cows.py 
...

order = sorted(cows.items(), key=lambda x: x[1], reverse= True)
order_copy = copy.copy(order)
print(order)
print(greedy_cow_transport(order_copy,capacity))
print(order)

输出

$ python3 cows.py 
[('Jesse', 6), ('Maggie', 5), ('Maybel', 3), ('Callie', 2)]
[['Jesse'], ['Callie', 'Maggie'], ['Maybel']]
[('Jesse', 6), ('Maggie', 5), ('Maybel', 3), ('Callie', 2)]

注意,如果有嵌套列表,则需要deepcopy。你知道吗

考虑这个例子:

def modify(arr):
    arr.remove(4)

numbers = [1, 2, 3, 7, 3, 4]
modify(numbers)
print(numbers) # prints [1, 2, 3, 7, 3] (modified)

您可能期望参数传递给函数的行为类似于整数:

def modify(i):
    i = 6

j = 7
modify(j)
print(j) # prints 7 (not modified)

您可能认为Python总是复制参数以在函数中使用,但事实并非如此。执行i = 6操作时,将变量名i设置为引用值为6的新对象。因此,不会修改全局i。你知道吗

但是,当您使用list.remove(x)时,您正在修改作为参数传递的实际对象。名为list的变量仍然引用原始对象。你知道吗

当然,这个解释可能会让人很困惑。添加一些id()将有助于澄清问题。你知道吗

def modify(arr):
    print(id(arr))
    arr.remove(4)
    print(id(arr)) # they print the same thing

numbers = [1, 2, 3, 7, 3, 4]
modify(numbers)
print(numbers) # prints [1, 2, 3, 7, 3] (modified)

现在使用整数:

def modify(i):
    print(id(i))
    i = 6
    print(id(i)) # nope, different ids!

j = 7
modify(j)
print(j) # prints 7 (not modified)

相关问题 更多 >