字典理解和 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 这些在上下文之外是有意义的,因此您可能想要添加更多信息,了解您实际想要实现的目标。
我使用列表 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 这些在上下文之外是有意义的,因此您可能想要添加更多信息,了解您实际想要实现的目标。