如何将 Python 'deque' 对象作为列表理解的一部分
How to prepend a Python 'deque' object as part of a list comprehension
我正在使用 jsonschema
验证 JSON 文档,如果有任何错误我需要捕获它们,包括文档中错误的路径。为确保路径永远不会为空(即,如果文档根目录中的必需键丢失),我希望在错误路径前添加 root.
v = jsonschema.Draft7Validator(schema_dict)
errors = sorted(v.iter_errors(payload_dict), key=lambda e: e.path)
if len(errors) > 0:
paths = ['.'.join(deque(('root')) + e.absolute_path) for e in errors]
messages = [f'{p}: {e.message}' for e, p in zip(errors, paths)]
raise InvalidPayloadException(messages) from None
例如,如果需要属性 obj.key1
和 obj.key2
并且测试了以下 JSON 文档。
{
"obj": {
"keyx": "value"
}
}
我希望messages
包含的是以下列表。
["root.obj: 'key1' is a required property", "root.obj: 'key2' is a required property"]
messages
实际包含的是root作为四个独立的元素。
["r.o.o.t.obj: 'key1' is a required property", "r.o.o.t.obj: 'key2' is a required property"]
如何修改我的代码,使消息包含预期的文本?最好,我想保持列表理解,因为它们往往易于阅读并且不会占用太多空间,但如果需要,我愿意改变它。
我还看到 deque
的文档提到了 appendleft()
,但使用它会导致错误。
paths = ['.'.join(e.absolute_path.appendleft('root')) for e in errors]
TypeError: 'NoneType' object is not iterable
所以,问题是您将单个字符串对象传递给 dequeue
构造函数,它像 Python 中的其他 sequence-like 构造函数一样工作,它接受任意可迭代对象并构造通过迭代可迭代对象出队。
但我注意到您使用了一组额外的括号,所以我认为您打算传递一个单例元组。你实际上需要一个逗号,所以你想要的是:
paths = ['.'.join(deque(('root',)) + e.absolute_path) for e in errors]
注意逗号。 deque(('root'))
-> deque(('root',))
不过,我认为这样做会更简洁:
paths = ['.'.join(['root', *e.absolute_path]) for e in errors]
我正在使用 jsonschema
验证 JSON 文档,如果有任何错误我需要捕获它们,包括文档中错误的路径。为确保路径永远不会为空(即,如果文档根目录中的必需键丢失),我希望在错误路径前添加 root.
v = jsonschema.Draft7Validator(schema_dict)
errors = sorted(v.iter_errors(payload_dict), key=lambda e: e.path)
if len(errors) > 0:
paths = ['.'.join(deque(('root')) + e.absolute_path) for e in errors]
messages = [f'{p}: {e.message}' for e, p in zip(errors, paths)]
raise InvalidPayloadException(messages) from None
例如,如果需要属性 obj.key1
和 obj.key2
并且测试了以下 JSON 文档。
{
"obj": {
"keyx": "value"
}
}
我希望messages
包含的是以下列表。
["root.obj: 'key1' is a required property", "root.obj: 'key2' is a required property"]
messages
实际包含的是root作为四个独立的元素。
["r.o.o.t.obj: 'key1' is a required property", "r.o.o.t.obj: 'key2' is a required property"]
如何修改我的代码,使消息包含预期的文本?最好,我想保持列表理解,因为它们往往易于阅读并且不会占用太多空间,但如果需要,我愿意改变它。
我还看到 deque
的文档提到了 appendleft()
,但使用它会导致错误。
paths = ['.'.join(e.absolute_path.appendleft('root')) for e in errors]
TypeError: 'NoneType' object is not iterable
所以,问题是您将单个字符串对象传递给 dequeue
构造函数,它像 Python 中的其他 sequence-like 构造函数一样工作,它接受任意可迭代对象并构造通过迭代可迭代对象出队。
但我注意到您使用了一组额外的括号,所以我认为您打算传递一个单例元组。你实际上需要一个逗号,所以你想要的是:
paths = ['.'.join(deque(('root',)) + e.absolute_path) for e in errors]
注意逗号。 deque(('root'))
-> deque(('root',))
不过,我认为这样做会更简洁:
paths = ['.'.join(['root', *e.absolute_path]) for e in errors]