我有以下代码
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会以这种方式运行?我完全理解第二个代码中会发生什么,但我不理解第一个代码的行为。
答案 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]