单行嵌套在Python中的循环

时间:2019-08-20 19:49:51

标签: python

我有一个看起来像这样的对象:

obj = {
    "outer_list": [
        {
            "inner_list_1": ["string1", "string2"]
        },
        {
            "inner_list_2": ["string3", "string4"]
        }
    ]
}

我想创建一个包含两个内部列表的新列表:

["string1", "string2", "string3", "string4"]

目前,我有这样的东西:

result = []
for inner_object in obj['outer_list']:
    for my_str in inner_object['inner_list']:
        result.append(my_str)

我想知道如何在一行中编写嵌套循环。

result = [...]

7 个答案:

答案 0 :(得分:1)

您可以使用this.personalDataForm.get('name').valueChanges.subscribe((x) => { console.log('value has changed: ', x); this.personalDataForm.patchValue({ username: x }); });

itertools.chain.from_iterables

因此,给定:

from itertools import chain
list(chain.from_iterable(d['inner_list'] for d in obj['outer_list']))

这将返回:

obj = {
    "outer_list": [
        {
            "inner_list": ["string1", "string2"]
        },
        {
            "inner_list": ["string3", "string4"]
        }
    ]
}

或者,如果您要解决问题中发布的数据,每个子字典中内部列表的键以从1开始的递增数字结尾,则可以使用['string1', 'string2', 'string3', 'string4'] 生成这样的数据递增数字:

enumerate

因此,给定:

list(chain.from_iterable(d['inner_list_%d' % n] for n, d in enumerate(obj['outer_list'], 1)))

这将返回:

obj = {
    "outer_list": [
        {
            "inner_list_1": ["string1", "string2"]
        },
        {
            "inner_list_2": ["string3", "string4"]
        }
    ]
}

答案 1 :(得分:0)

Python中的嵌套符号是我见过的最奇怪的符号。 其构造[x for y in z for x in y]

result = [ my_str for  inner_object in obj['outer_list'] for my_str in inner_object ['inner_list']]

答案 2 :(得分:0)

尝试一下:

result = []
for inner_object in obj['outer_list']:
    for k in inner_object:
        result.extend(inner_object[k])

这里是单线:

result = [i for inner_object in obj['outer_list'] for v in inner_object.values() for i in v]

输出

['string1', 'string2', 'string3', 'string4']

答案 3 :(得分:0)

如果我不得不一行完成,那么我可能会这样做。

import itertools
result = list(itertools.chain.from_iterable([tuple(el.values())[0] for el in d['outer_list']]))

收益

['string1', 'string2', 'string3', 'string4']

但是您已经想出的解决方案要好得多。

答案 4 :(得分:0)

您可以使用理解来做到这一点,但这会因内部对象而带来一些风险:

resultList = [ stringVal for stringVal in x for x in y.values() for y in obj['outer_list']]
>>> resultList
['string3', 'string3', 'string4', 'string4']

答案 5 :(得分:0)

您可以使用reduce来实现

from functools import reduce
result = list(reduce(lambda x,y: x['inner_list']+y['inner_list'], obj['outer_list']))

答案 6 :(得分:0)

[item for inner_dict in obj["outer_list"] for item in list(inner_dict.values())[0]]

列表推导由两部分组成:表达式和循环。您可以认为列表理解是list(get_items())的简写,其中get_items被定义为

def get_items():
       loop:
            yield(expression)

在这种情况下,loop

       for inner_dict in obj["outer_list"]:
           for item in list(inner_dict.values())[0]:

expressionitem

因此,列表理解的格式是首先编写要进行yield处理的内容(在这种情况下为item),然后编写经过迭代的循环以获取这些收益。

如果需要,可以尝试一下:

def get_items():              
   for inner_dict in obj["outer_list"]:
       for item in list(inner_dict.values())[0]:
           yield(item)
list(get_items())

循环也可以写成

for inner_dict in obj["outer_list"]:
    for inner_list in list(inner_dict.values()):
        for item in inner_list:
            yield(item)

这将导致列表理解

[item for inner_dict in obj["outer_list"] for inner_list in inner_dict.values() for item in inner_list]