列表中的 Python 3 奇数函数行为

标签 python python-3.x scope

所以我在 python 3.3 中使用列表,这是我的示例代码:

def change_to_z(lis):
    lis[3] = 'z'

def change_to_k(lis):
    lis[4] = 'k'


def split(lis):
    lis = lis[3:] + lis[:3]

totest = ['a', 'b', 'c', 'd', 'e', 'f']

change_to_z(totest)
print(totest)
change_to_k(totest)
print(totest)
split(totest)
print(totest)

和输出:

['a', 'b', 'c', 'z', 'e', 'f']
['a', 'b', 'c', 'z', 'k', 'f']
['a', 'b', 'c', 'z', 'k', 'f']

请注意,当我调用前两个函数时,我能够修改列表,而 totest 始终引用列表,即使它已更改。

但是,有了第三个函数,变量totest不再引用列表的最新修改版本。我的调试器告诉我,在函数“split”中,列表被翻转了,但在函数之外,它没有翻转。为什么变量名不再引用列表?

为什么会这样?这会发生在哪些运营商身上?为什么有时变量名在函数中被修改后仍然引用列表,但它与其他运算符的行为不同?

最佳答案

你对函数的 scope 的理解是错误的。

如果你真的想更改提供的列表,你可以尝试以下两种方法之一。

def split(lis):
    global lis
    lis = lis[3:] + lis[:3]

或者更好

def split(lis):
    lis[:] = lis[3:] + lis[:3] # Credits go to drewk for pointing this out

当你在做的时候

def split(lis):
    lis = lis[3:] + lis[:3]

split 函数中,您正在创建一个本地列表,其标识符与提供的列表的标识符相同。但是,这两者不会冲突,因为传递的列表是全局

如果你想玩玩并知道它们是否真的不同,请使用 id()

lis = [1, 2, 3]
def split(lis):
    lis = lis[3:] + lis[:3]
    print id(lis)
split(lis)
print id(lis)

上述代码的输出

40785920
40785600

注意内存位置有何不同

关于列表中的 Python 3 奇数函数行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19782044/

相关文章:

python - 在snakemake中使用expand()从目录列表中输入任何文件

python - 为什么这个 flask-admin 表单总是验证失败?

python - 如何让窗口聚焦于 Windows 并调整它的大小?

python - 如何并行迭代两个列表?

python - 访问多个嵌套字典以返回最小的键和值

ruby-on-rails - Rails 3 - 访问范围链以重用

javascript - 设置函数默认this值

python - 当我一开始就没有使用 xrange 时,为什么没有定义 xrange?

python - 正则表达式,在匹配条上并捕获?

python - 模块中的全局变量范围