假设我有一个包含(除其他外)不同类型的子列表的列表:
[1, 2, [3, 4], {5, 6}]
我想以有选择的方式展平,具体取决于其元素的类型(即我只想展平sets
,其余的不展平):
[1, 2, [3, 4], 5, 6]
我目前的解决方案是一个函数,但只是为了我的求知欲,我想知道是否可以用一个列表理解来做到这一点?
假设我有一个包含(除其他外)不同类型的子列表的列表:
[1, 2, [3, 4], {5, 6}]
我想以有选择的方式展平,具体取决于其元素的类型(即我只想展平sets
,其余的不展平):
[1, 2, [3, 4], 5, 6]
我目前的解决方案是一个函数,但只是为了我的求知欲,我想知道是否可以用一个列表理解来做到这一点?
列表推导不是为展平而设计的(因为它们无法组合与多个输入项对应的值)。
虽然您可以使用嵌套列表推导来解决这个问题,但这需要顶级列表中的每个元素都是可迭代的。
老实说,只需为此使用一个函数。这是最干净的方式。
Amber 可能是正确的,因为这样的功能更可取。另一方面,总是有一些变化的空间。我假设嵌套的深度永远不会超过一层——如果它的深度超过一层,那么你绝对应该更喜欢这个函数。但如果不是,这是一种潜在可行的方法。
>>> from itertools import chain
>>> from collections import Set
>>> list(chain.from_iterable(x if isinstance(x, Set) else (x,) for x in l))
[1, 2, [3, 4], 5, 6]
执行此操作的非 itertools 方法将涉及嵌套列表推导。最好把它分成两行:
>>> packaged = (x if isinstance(x, collections.Set) else (x,) for x in l)
>>> [x for y in packaged for x in y]
[1, 2, [3, 4], 5, 6]
对于这些中的任何一个是否会比简单的函数更快或更慢,我没有强烈的直觉。这些创建了很多单例元组——这有点浪费——但它们也以 LC 速度发生,这通常非常好。
您可以使用来自funcy库的flatten函数:
from funcy import flatten, isa
flat_list = flatten(your_list, follow=isa(set))
你也可以看看它的实现。