if else使用python list comprehension嵌套for循环

时间:2017-07-06 16:01:13

标签: python python-2.7 list-comprehension

任何人都可以帮我找出产生以下输出的列表理解方法 -

让列表为 -

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循环来获得类似的输出?

我无法在列表理解

的情况下尝试访问内部for循环

我的尝试 -

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

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:1)

列表推导具有固定数量的(嵌套)循环。所以必须在这里有两个循环,一个在顶级词典上,一个在fields上。诀窍是如果没有字段,在嵌套循环中产生一个迭代:

[d['name'] + fieldname 
 for d in results
 for fieldname in (
    ('.' + sub['name'] for sub in d['fields']) if 'fields' in d else
    ('',))
]

for fieldname循环 覆盖fields子目录的名称(带有'.'前缀),在一个元组中只有一个空字符串。

请注意,这实际上并非可读。我将委托生成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']