嵌套字典理解:解包的值太多

Nested dictionary comprehension: Too many values to unpack

我尝试重写以下代码来处理字典理解,只是为了好玩:

import itertools

with open('foo.txt') as f:
    entities = f.read().splitlines()

parsed_entities = []
while entities:
    props = itertools.takewhile(lambda n: n != 'EOM', entities)
    entity = {p.split('=')[0]: p.split('=')[1] for p in props}
    entities = entities[len(entity)+2:]  # Delete and skip EOM & newline
    parsed_entities.append(entity)

我想替换这一行:

entity = {p.split('=')[0]: p.split('=')[1] for p in props}

更好看的字典理解,可能看起来像:

entity = {key: value for p in props for key, value in p.split('=')}

当我尝试这样做时,出现以下错误:

ValueError: too many values to unpack (expected 2)

我做错了什么?使用 ipdb.pm() 我看到 p 是 name=yam,这很好,但是 keyvalue 是未定义的。

你不能这样做:

for key, value in p.split('=')

因为这要求 p.split() 调用的每个结果都恰好有 两个 元素。相反,您只有一系列长度可变的单个(字符串)元素。

您必须先将 p.split() 包装到另一个可迭代对象中:

entity = {key: value for p in props for key, value in (p.split('='),)}

所以现在代替:

['key', 'value']

你得到:

(['key', 'value'],)

它只迭代 一次,提供两个要解包的值。

但是,您可以在这里使用 dict() 可调用函数;它直接消耗 (key, value) 对的迭代:

entity = dict(p.split('=') for p in props)

你也应该尽量避免将整个文件读入内存,你可以将文件作为可迭代直接使用:

from itertools import takewhile

parsed_entities = []
with open('foo.txt') as f:
    cleaned = (l.rstrip('\n') for l in f)
    while True:
        props = takewhile(lambda n: n != 'EOM', cleaned)
        parsed_entities.append(dict(p.split('=') for p in props))
        try:
            next(cleaned)  # consume line after EOM
        except StopIteration:
            # no more lines
            break