自deprecation of the compiler package以来,推荐的扁平化嵌套列表的方法是什么?
>>> from compiler.ast import flatten
>>> flatten(["junk",["nested stuff"],[],[[]]])
['junk', 'nested stuff']
我知道有一些堆栈溢出解决列表扁平化的方法,但我希望使用pythonic式的标准包,“一种,最好只有一种明显的方法”来做到这一点。
发布于 2013-04-24 02:49:09
您声明的函数接受一个嵌套列表,并将其展平为一个新列表。
为了将一个任意嵌套的列表展平为一个新列表,这在Python 3上如您所愿地工作:
import collections
def flatten(x):
result = []
for el in x:
if isinstance(x, collections.Iterable) and not isinstance(el, str):
result.extend(flatten(el))
else:
result.append(el)
return result
print(flatten(["junk",["nested stuff"],[],[[]]]))
打印:
['junk', 'nested stuff']
如果你想要一个做同样事情的生成器:
def flat_gen(x):
def iselement(e):
return not(isinstance(e, collections.Iterable) and not isinstance(e, str))
for el in x:
if iselement(el):
yield el
else:
for sub in flat_gen(el): yield sub
print(list(flat_gen(["junk",["nested stuff"],[],[[[],['deep']]]])))
# ['junk', 'nested stuff', 'deep']
对于Python3.3和更高版本,请使用yield from而不是循环:
def flat_gen(x):
def iselement(e):
return not(isinstance(e, collections.Iterable) and not isinstance(e, str))
for el in x:
if iselement(el):
yield el
else:
yield from flat_gen(el)
发布于 2014-06-05 01:20:24
from funcy import flatten, isa
flat_list = flatten(your_list)
您还可以显式指定要遵循的值:
# Follow only sets
flat_list = flatten(your_list, follow=isa(set))
如果你想要一个算法节奏,可以看看its implementation。
发布于 2013-04-24 02:49:52
对于具有任意嵌套的列表,没有内置的方法,但类似于以下内容...
def flatten(l):
for i in l:
if isinstance(i, (list, tuple)):
for ii in flatten(i):
yield ii
else:
yield i
>>> l = ["junk",["nested stuff"],[],[[]]]
>>> list(flatten(l))
['junk', 'nested stuff']
...will适用于列表和元组。如果您想要支持任何可以在for item in object
表达式中使用的对象,那么最好使用如下所示的鸭子类型...
def flatten(l):
for i in l:
if isinstance(i, (str, bytes)):
yield i
else:
try:
for ii in flatten(i):
yield ii
except TypeError:
yield i
>>> l = ["junk",["nested stuff"],[],[[]]]
>>> list(flatten(l))
['junk', 'nested stuff']
与检查isinstance(el, Iterable)
相比,...which稍微更健壮一些,因为它不能处理某些情况,例如...
class Range10:
def __getitem__(self, index):
if index >= 10:
raise IndexError
return index
>>> import collections
>>> r10 = Range10()
>>> isinstance(r10, collections.Iterable)
False
>>> list(Range10())
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
https://stackoverflow.com/questions/16176742
复制相似问题