首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Python3替代过时的compiler.ast扁平化函数

Python3替代过时的compiler.ast扁平化函数
EN

Stack Overflow用户
提问于 2013-04-24 02:37:38
回答 6查看 8.1K关注 0票数 10

deprecation of the compiler package以来,推荐的扁平化嵌套列表的方法是什么?

代码语言:javascript
复制
>>> from compiler.ast import flatten
>>> flatten(["junk",["nested stuff"],[],[[]]])
['junk', 'nested stuff']

我知道有一些堆栈溢出解决列表扁平化的方法,但我希望使用pythonic式的标准包,“一种,最好只有一种明显的方法”来做到这一点。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-04-24 02:49:09

您声明的函数接受一个嵌套列表,并将其展平为一个新列表。

为了将一个任意嵌套的列表展平为一个新列表,这在Python 3上如您所愿地工作:

代码语言:javascript
复制
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"],[],[[]]]))  

打印:

代码语言:javascript
复制
['junk', 'nested stuff']

如果你想要一个做同样事情的生成器:

代码语言:javascript
复制
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而不是循环:

代码语言:javascript
复制
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)   
票数 6
EN

Stack Overflow用户

发布于 2014-06-05 01:20:24

您可以使用funcy库中的flatten函数:

代码语言:javascript
复制
from funcy import flatten, isa
flat_list = flatten(your_list)

您还可以显式指定要遵循的值:

代码语言:javascript
复制
# Follow only sets
flat_list = flatten(your_list, follow=isa(set))

如果你想要一个算法节奏,可以看看its implementation

票数 4
EN

Stack Overflow用户

发布于 2013-04-24 02:49:52

对于具有任意嵌套的列表,没有内置的方法,但类似于以下内容...

代码语言:javascript
复制
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表达式中使用的对象,那么最好使用如下所示的鸭子类型...

代码语言:javascript
复制
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稍微更健壮一些,因为它不能处理某些情况,例如...

代码语言:javascript
复制
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]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16176742

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档