字典理解和 os.listdir() - python3

Dictionary comprehension and os.listdir() - python3

我使用列表 os.listdir('./foo') 中的长度和元素创建了以下字典理解(第一行代码组)。生成的字典不是我所期望的。为什么会这样?

  >>>folder = {k : v for k in range(len(os.listdir('./foo'))) for v in os.listdir('./foo')}
  >>>print(folder)
  >>>{0: 'foo0', 1: 'foo0', 2: 'foo0', 3: 'foo0'}

但是

>>>print(os.listdir('./foo'))
>>>{0: 'foo0', 1: 'foo1', 2: 'foo2', 3: 'foo3'}

所以,我期待的是下面的字典,而不是第一个。

  >>>folder = {k : v for k in range(len(os.listdir('./foo'))) for v in os.listdir('./foo')}
  >>>print(folder)
  >>>{0: 'foo0', 1: 'foo1', 2: 'foo2', 3: 'foo3'}

谢谢

你没有正确理解字典,你不应该有 2 个不同的 for 语句。相反,使用 zip:

folder = {k : v for k,v in zip(range(len(os.listdir('./foo'))), os.listdir('./foo'))}

甚至更好,使用 enumerate():

folder = {k : v for k,v in enumerate(os.listdir('./foo'))}

将您的原始理解重写为嵌套的 for 循环,它在逻辑上(大约)表示:

folder = {}
for v in os.listdir('./foo'):
    for k in range(len(os.listdir('./foo'))):
        folder[k] = v

除了重复调用 os.listdir 之外,您还为每个键将多个项目插入到字典中。正确的理解应该是:

folder = {k: v for (k, v) in enumerate(os.listdir('./foo'))}

在相关说明中,os.listdir() 的结果是一个列表,而不是字典,所以

>>> print(os.listdir('./foo'))
['foo0', 'foo1', 'foo2', 'foo3']

比您发布的情况更有可能发生。

看来您对字典理解的语义不太正确:

{k : v for k in range(len(os.listdir('./foo'))) for v in os.listdir('./foo')}

等同于“os.listdir() 遍历所有 v 并且对于其中的每一个 v 从 [=17] 遍历所有 k =].

因为一个简单的字典不能保存重复的 k-v-对,所以最后一个赋值很重要,因此上面基本上等同于:

{k : os.listdir('./foo')[-1] for k in range(len(os.listdir('./foo')))}

请注意,语义与理解式写成

相同
dict((k, v) for k in range(len(os.listdir('./foo'))) for v in os.listdir('./foo'))

None 这些在上下文之外是有意义的,因此您可能想要添加更多信息,了解您实际想要实现的目标。