我可以将包含词典的列表以及列表理解范围内的词典列表压平吗



我有一个函数,它可以根据传递的参数返回字典或字典列表。MWE如下所示:

def do_something(condition: bool):
if not condition:
return {"foo": "bar"}
return [{"foo": "bar"}, {"foo": "bar"}]
my_array = [False, False, True, False]
result = [do_something(i) for i in my_array]
print(result)

我想做的是使result包含单个字典的列表,而不是将一些元素作为字典的列表。所以目前,这个代码的结果是:

[{'foo': 'bar'}, {'foo': 'bar'}, [{'foo': 'bar'}, {'foo': 'bar'}], {'foo': 'bar'}]']

但我希望结果是:

[{'foo': 'bar'}, {'foo': 'bar'}, {'foo': 'bar'}, {'foo': 'bar'}, {'foo': 'bar'}]

有没有任何方法可以使用列表理解来实现这个结果,或者我需要使用for循环并在进行时附加到列表中?

我唯一的想法是看看是否有一种方法可以使用*运算符打开列表,但这不起作用:

return *[{"foo": "bar"}, {"foo": "bar"}  # Can't used starred expression here.

UPDATE我在这个线程中标记了一个已接受的答案,但我通过使用itertools.chain.from_iterable()获得了相同的结果

所以我的代码现在是:

import itertools  # Extra import I needed
result = list(
itertools.chain.from_iterable([do_something(i) for i in my_array])
)

你可以试试这个

from collections import Iterable
def flatten(lst):
for elm in lst:
if isinstance(elm, Iterable) and not isinstance(elm, (str, bytes, dict)):
yield from flatten(elm)
else:
yield elm

l = [{'foo': 'bar'}, {'foo': 'bar'}, [{'foo': 'bar'}, {'foo': 'bar'}], {'foo': 'bar'}]
flatten = list(flatten(l))

输出:

如果您不希望dict对象出现在展开列表中,则可以从isinstance((检查中删除dict

如果您的Python是3.8或更高版本:

def do_something(condition: bool):
if not condition:
return {"foo": "bar"}
return [{"foo": "bar"}, {"foo": "bar"}]
my_array = [False, False, True, False]
[(result := []) if i is None 
else [result.append(do_something(j)) if not j 
else result.extend(do_something(j)) 
for j in i] 
for i in (None, my_array)]
print(result) 
#[{'foo': 'bar'}, {'foo': 'bar'}, {'foo': 'bar'}, {'foo': 'bar'}, {'foo': 'bar'}]

最新更新