缩短Python列表理解

时间:2019-07-02 03:29:57

标签: python python-3.x

我是来自JavaScript背景的人。

是否存在更干净,更Python化的方法来编写以下内容,同时将其保持在80个字符以内,以遵循标准的flake8样式指南规则?

i = next((i for i, entry in enumerate(toc[key]) if ('file' in entry and entry['file'] == name) or ('guide_directory' in entry and entry['guide_directory'] == name)), None)

5 个答案:

答案 0 :(得分:1)

您可以根据需要缩进列表理解,因为它们被方括号或父母包围。只是一个例子

i = next((i for i, entry in enumerate(toc[key]) 
            if ('file' in entry and entry['file'] == name) or 
               ('guide_directory' in entry and 
                entry['guide_directory'] == name)),
         None)

有一些可能的重构方式

('file' in entry and entry['file'] == name)`

可以

entry.get('file') == name

('guide_directory' in entry and entry['guide_directory'] == name)

相同

我想以上对您的情况同样有效,

i = next((i for i, entry in enumerate(toc[key]) 
            if name and name in (entry.get('file'), entry.get('guide_directory')),
         None)

如果您确定名称不为None,则该名称更短

i = next((i for i, entry in enumerate(toc[key]) 
            if name in (entry.get('file'), entry.get('guide_directory')),
         None)

答案 1 :(得分:1)

这是一个更简洁的版本:

next(
   (i for i, entry in enumerate(toc[key]) if name in {
             entry.get('file'),
            entry.get('guide_directory')}),
   None)

答案 2 :(得分:0)

您应将get用于dict,而不要检查密钥是否是indict

i = next((i for i, entry in enumerate(toc[key]) 
            if entry.get('file') == name or 
               entry.get('guide_directory') == name),
         None)

答案 3 :(得分:0)

如果name不能为None,则可以使用dict.get

i = next((i for i, entry in enumerate(toc[key]) if entry.get('file') == name or entry.get('guide_directory') == name), None)

然后in

i = next((i for i, entry in enumerate(toc[key]) if name in (entry.get('file'), entry.get('guide_directory')), None)

然后创建一个函数:

def find_index(iterable, predicate):
    return next((i for i, x in enumerate(iterable) if predicate(x)), None)


i = find_index(toc[key], lambda entry:
        name in (entry.get('file'), entry.get('guide_directory')))

答案 4 :(得分:0)

除非行本身就是有效的语句,否则不需要使用显式的行继续。因此,您可以将结果包装在括号中以继续执行该语句。这通常用于长字符串。

例如

foobar = "This is a really really long string that could not normally doesnt look very good because its too long for a simple line of code"

foobar = (
    "This is a really really long string "
    "that could not normally doesnt look "
    "very good because its too long for a "
    "simple line of code"
)

以下是同一条语句(也可以使用get安全地检查字典,而无需进行键检查):

i = next(
    (
        i for i, entry in enumerate(toc[key]) 
        if (
            entry.get('file') == name 
            or entry.get('guide_directory') == name
        )
    ),
    None,
)

另一个风格点是将复杂的逻辑分解成自己的方法。这使您既可以对内部组件进行单元测试,又可以稍后再使用。这是我写该语句的方式:

def valid_entry(name: str, entry: Dict[str, Any]) -> bool:
    return (
       entry.get('file') == name 
       or entry.get('guide_directory') == name
    )

generator = (
    i for i, entry in enumerate(toc[key]) 
    if valid_entry(name, entry)
)
i = next(generator, None)
相关问题