列出作为函数参数 - 丢弃修改

时间:2014-11-04 08:11:32

标签: python function reference arguments argument-passing

我有以下代码

def hidePasswords(L, password):
    for elem in L:
        if elem == password:
            elem = "*"*len(password)
    return L

print(hidePasswords(["test","test1","test8"],"test"))

它返回['test', 'test1', 'test8']而不是['****', 'test1', 'test8']。当我将我的功能改为

def hidePasswords(L, password):
    temp = []
    for elem in L:
        if elem == password:
            elem = "*"*len(password)
        temp.append(elem)
    return temp

它可以正常工作。

为什么Python会以这种方式运行?我完全理解第二个代码中会发生什么,但我不理解第一个代码的行为。

2 个答案:

答案 0 :(得分:2)

凯尔伍德已经给出了一个很好的答案(像往常一样),但我只想补充几点。

考虑Python如何根据其他语言(如按值传递和传递引用)的概念进行工作并不是那么有用。不要考虑变量,它们的内容和指向它们的内容,而是尝试采用Pythonic观点并根据对象绑定到名称以及对象(及其内容)是否可变来进行思考。

这些概念不仅对于理解在Python中调用函数时会发生什么很重要,它通常适用于简单的赋值。换句话说,尽管赋值语句可能看起来就像其他语言中的赋值语句一样,真正发生的事情并不完全相同。

Stack Overflow常规Ned Batchelder有一篇很棒的文章,上面有关于这个主题的可爱图表:Facts and myths about Python names and values

这是您的代码的变体,它会改变传递给它的列表。通常的Python惯例是,变异对象的函数不返回它(尽管有时弯曲该约定很方便)。

#! /usr/bin/env python

def hidePasswords(L, password):
    for i, elem in enumerate(L):
        if elem == password:
            L[i] = "*" * len(password)
    return

words = ["test", "test1", "test8"]
hidePasswords(words, "test")
print(words)

<强>输出

['****', 'test1', 'test8']

答案 1 :(得分:1)

在此代码中:

def hidePasswords(L, password):
    for elem in L:
        if elem == password:
            elem = "*"*len(password)
    return L

在循环中,elem被设置为L中的每个值。然后你重新分配elem是不同的东西。所以 L中的值,那么它就是其他东西。这不会影响L中的值,因为elem不是参考。

你可以更简洁地写这个:

def hidePasswords(L, password):
    return ['*'*len(password) if elem==password else elem for elem in L]