Python列表推导式中使用if else嵌套的for循环

4

请问有人可以帮我想出用列表推导式生成下面的输出吗:

给定一个列表:

results = [
    {"id":  1, "name":  "input"},
    {"name": "status", "desc": "Status"},
    {"name": "entity", "fields": [
        {"id": 101, "name": "value"},
        {"id": 102, "name": "address"}]
    }
]

我希望您能将输出以列表形式呈现。获取输出的代码如下:

output = []
for eachDict in results:
    if "fields" in eachDict:
        for field in eachDict["fields"]:
            output.append(eachDict["name"]+"."+field["name"])
    else:
        output.append(eachDict["name"])

因此,使用上述代码的输出为 -
['input', 'status', 'entity.value', 'entity.address']

是否可以使用if else嵌套for循环在列表推导中获得类似的输出?

我正在尝试访问列表推导式中if条件中的内部for循环,但遇到了困难。

我的尝试 -

output = [eachDict["name"]+"."+field["name"] for field in eachDict["fields"] if "fields" in eachDict else eachDict["name"] for eachDict in results]

这段代码可以运行,但不是一个好的代码。为了提高可读性,应该将任务委托给函数:[item for sublist in [['{0}.{1}'.format(d['name'], f['name']) for f in d['fields']] if 'fields' in d else [d['name']] for d in results] for item in sublist] - Dom Weldon
2个回答

7

将代码转换为可工作代码的一种方法是使内部循环生成列表,然后在之后展平结果。

sum(([d['name'] + '.' + f['name'] for f in d['fields']] 
    if d.get('fields') else [d['name']] for d in results), [])

3
一个列表推导式有固定数量的(嵌套)循环。因此,在这里必须有两个循环,一个是在顶层字典上进行的,另一个是在“fields”上进行的。诀窍在于:如果没有字段,则在嵌套循环中产生一个迭代。
[d['name'] + fieldname 
 for d in results
 for fieldname in (
    ('.' + sub['name'] for sub in d['fields']) if 'fields' in d else
    ('',))
]
< p > for fieldname 循环可以循环要么字段子目录的名称(带有前缀'.'),要么仅包含一个空字符串元组。

请注意,这实际上并不是非常易读。为了改善可读性,我会将生成fieldname循环的任务委托给一个辅助生成器函数:

def fieldnames(d):
    if 'fields' in d:
        for sub in d['fields']:
            yield '.' + sub['name']
    else:
        yield ''

[d['name'] + fieldname for d in results for fieldname in fieldnames(d)]

演示:

>>> def fieldnames(d):
...     if 'fields' in d:
...         for sub in d['fields']:
...             yield '.' + sub['name']
...     else:
...         yield ''
...
>>> [d['name'] + fieldname for d in results for fieldname in fieldnames(d)]
['input', 'status', 'entity.value', 'entity.address']

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接