简体   繁体   English

选择性展平Python列表

[英]Selective flattening of a Python list

Suppose I have a list containing (among other things) sublists of different types: 假设我有一个包含(以及其他)不同类型的子列表的列表:

[1, 2, [3, 4], {5, 6}]

that I'd like to flatten in a selective way, depending on the type of its elements (ie I'd like to only flatten sets , and leave the rest unflattened): 我想以一种选择性的方式扁平化,这取决于它的元素类型(即我只想展平sets ,而其余​​部分保持不平整):

[1, 2, [3, 4], 5, 6]

My current solution is a function, but just for my intellectual curiosity, I wonder if it's possible to do it with a single list comprehension? 我目前的解决方案是一个功能,但仅仅是出于我的求知欲,我想知道是否可以用一个列表理解来做到这一点?

List comprehensions aren't designed for flattening (since they don't have a way to combine the values corresponding to multiple input items). 列表推导不是为扁平化而设计的(因为它们没有办法组合对应于多个输入项的值)。

While you can get around this with nested list comprehensions, this requires each element in your top level list to be iterable. 虽然您可以使用嵌套列表推导来解决这个问题,但这需要您的顶级列表中的每个元素都是可迭代的。

Honestly, just use a function for this. 老实说,只需使用一个功能。 It's the cleanest way. 这是最干净的方式。

Amber is probably right that a function is preferable for something like this. 琥珀可能是正确的,因为这样的功能更适合。 On the other hand, there's always room for a little variation. 另一方面,总有一点变化的空间。 I'm assuming the nesting is never more than one level deep -- if it is ever more than one level deep, then you should definitely prefer a function for this. 我假设嵌套永远不会超过一个级别 - 如果它的深度超过一个级别,那么你肯定更喜欢这个功能。 But if not, this is a potentially viable approach. 但如果没有,这是一种潜在可行的方法。

>>> 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]

The non-itertools way to do this would involve nested list comprehensions. 非itertools的方法将涉及嵌套列表推导。 Better to break that into two lines: 最好将其分为两行:

>>> 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]

I don't have a strong intuition about whether either of these would be faster or slower than a straightforward function. 我对这些中的任何一个是否比直接函数更快或更慢都没有强烈的直觉。 These create lots of singleton tuples -- that's kind of a waste -- but they also happen at LC speed, which is usually pretty good. 这些会产生很多单例元组 - 这有点浪费 - 但它们也是以LC速度发生的,这通常都很好。

You can use flatten function from funcy library: 您可以使用funcy库中的flatten函数:

from funcy import flatten, isa

flat_list = flatten(your_list, follow=isa(set))

You can also peek at its implementation . 您还可以查看其实现

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM