【问题标题】:Why can't reset the dictionary? [duplicate]为什么不能重设字典? [复制]
【发布时间】:2020-04-07 04:05:24
【问题描述】:

我写了一个函数来递归列出所有文件和目录。

import os
def walk_dir(path,dir_list=[],file_list=[]):
    for fname in os.listdir(path):
        fullname = os.path.join(path, fname)
        if  os.path.isdir(fullname) :
            dir_list.append(fullname)
            walk_dir(fullname,dir_list,file_list)
        elif os.path.isfile(fullname) :
            file_list.append(fullname)
    return {'dir':dir_list,'file':file_list}

它返回一个字典。
我创建了一个目标目录来测试我的代码。

 mkdir -p /tmp/test
 cd /tmp/test
 mkdir -p  test{1..3}
 cd  test1
 touch /test1/test1{1..3}
 cd ../test2
 touch /test2/test2{1..2}

这是我要尝试的目标目录:

tree  /tmp/test
/tmp/test
├── test1
│   ├── test11
│   ├── test12
│   └── test13
├── test2
│   ├── test21
│   └── test22
├── test3

获取/tmp/test中的所有目录和文件。

x = walk_dir('/tmp/test')
x['dir']
['/tmp/test/test1', '/tmp/test/test3', '/tmp/test/test2']

现在将 x 重置为 {}--字典不包含任何内容。

x = {}
x
{}
x['dir']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'dir'
dir_list
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'dir_list' is not defined

也许每个变量都被初始化为无。
第二次获取文件和目录:

x = walk_dir('/tmp/test')
x['dir']
['/tmp/test/test1', '/tmp/test/test3', '/tmp/test/test2', '/tmp/test/test1', '/tmp/test/test3', '/tmp/test/test2']

我已将x 重置为{},为什么 x['dir'] 包含 6 个目录而不是 3 个目录?

【问题讨论】:

标签: python dictionary recursion


【解决方案1】:

这是 Python 的陷阱之一。

空列表的默认参数是在函数定义中创建的。它在函数调用之间仍然存在。

您可以在此处看到它的演示。 test_func 是一个具有列表默认参数的函数。然后修改列表,修改存在,每次函数运行都会改变。

>>> def test_func(param=[]):
...     param.append(1)
...     print(param)
... 
>>> test_func()
[1]
>>> test_func()
[1, 1]
>>> test_func()
[1, 1, 1]
>>> test_func()
[1, 1, 1, 1]
>>> test_func()
[1, 1, 1, 1, 1]
>>> test_func()
[1, 1, 1, 1, 1, 1]

如果您查看输出,您会看到重复项。每条路径存在两次。如果你再次运行它,它应该有三个重复,依此类推。这仅适用于可变类型。所以列表和字典之类的东西会表现出这种行为。如果您不打算使用此行为,请避免将它们用作默认参数。

改为使用将默认参数设置为 None 并在函数体中检查它。

>>> def test_func2(param=None):
...     if param is None:
...         param = []
...     param.append(1)
...     print(param)
... 
>>> test_func2()
[1]
>>> test_func2()
[1]
>>> test_func2()
[1]

【讨论】:

    猜你喜欢
    • 2019-03-30
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-18
    相关资源
    最近更新 更多