Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3替换已弃用的compiler.ast flant函数_Python_Python 3.x_Flatten - Fatal编程技术网

Python 3替换已弃用的compiler.ast flant函数

Python 3替换已弃用的compiler.ast flant函数,python,python-3.x,flatten,Python,Python 3.x,Flatten,自发布以来,建议采用什么方法展平嵌套列表 我知道列表展平有一些堆栈溢出的解决方案,但我希望pythonic的标准包“一种,最好只有一种,明显的方法”可以做到这一点。是将任何嵌套的iterable展平到一个级别的最佳解决方案-它比任何纯python解决方案都高效 这就是说,它将在所有的iterables上工作,因此,如果您希望避免它使字符串变平,则需要进行一些检查 同样,它也不会神奇地变平到任意深度。这就是说,一般来说,这样一个通用的解决方案是不需要的-相反,最好保持您的数据结构化,这样它就不需要

自发布以来,建议采用什么方法展平嵌套列表

我知道列表展平有一些堆栈溢出的解决方案,但我希望pythonic的标准包“一种,最好只有一种,明显的方法”可以做到这一点。

是将任何嵌套的iterable展平到一个级别的最佳解决方案-它比任何纯python解决方案都高效

这就是说,它将在所有的iterables上工作,因此,如果您希望避免它使字符串变平,则需要进行一些检查

同样,它也不会神奇地变平到任意深度。这就是说,一般来说,这样一个通用的解决方案是不需要的-相反,最好保持您的数据结构化,这样它就不需要以这种方式扁平化

编辑:我认为,如果必须进行任意展平,这是最好的方法:

import collections

def flatten(iterable):
    for el in iterable:
        if isinstance(el, collections.Iterable) and not isinstance(el, str): 
            yield from flatten(el)
        else:
            yield el
记住在2.x中使用
basestring
over
str
,在展平(el)中为subel使用
:产生el
,而不是3.3之前的
从展平(el)产生收益

正如评论中所指出的,我认为这是一种核选择,可能会造成比解决问题更多的问题。相反,最好的方法是使输出更加规则(例如,包含一个项的输出仍然以一个项元组的形式提供),并在引入该项的地方按一个级别进行规则展平,而不是在最后进行所有展平


这将产生更具逻辑性、可读性和更易于使用的代码。当然,在某些情况下,您需要进行这种展平(如果数据来自您无法处理的地方,因此您别无选择,只能采用结构不良的格式),在这种情况下,可能需要这种解决方案,但一般来说,这可能是个坏主意。

您所述的函数获取一个嵌套列表并将其展平为一个新列表

要将任意嵌套的列表展平为新列表,这将在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']
对于Python 3.3及更高版本,请使用以下命令代替循环:

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)   

对于具有任意嵌套的列表,没有内置的方法,但是类似这样的东西

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']
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']
…适用于列表和元组。如果您想支持在对象
表达式的
for item中可以使用的任何对象,那么最好像这样使用duck类型

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']
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)
稍微健壮一些,因为它无法处理某些情况,例如

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]

我的丑陋
while chain
解决方案,只是为了好玩:

from collections import Iterable
from itertools import chain

def flatten3(seq, exclude=(str,)):
    sub = iter(seq)
    try:
        while sub:
            while True:
                j = next(sub)
                if not isinstance(j, Iterable) or isinstance(j, exclude):
                    yield j
                else:
                    sub = chain(j, sub)
                    break
    except StopIteration:
        return
您可以使用库中的函数:

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

# Follow only sets
flat_list = flatten(your_list, follow=isa(set))

如果您想要一个算法,请看一看。

为递归构建:Python 3.6

def flatten(lst):
    """Flattens a list of lists"""
    return [subelem for elem in lst 
                    for subelem in elem]

在列表中定义您的类型,并使用any内置项检查另一个递归:Python 3.6。适用于列表/字符串/数字的复杂嵌套列表以及以下所有内容的组合:

def list_flattener(nestedList):  
    nonListElems=[]
    listElems=[]
    nestedListCounter=0
    for nc in range(len(nestedList)):
        if type(nestedList[nc])==list:
            nestedListCounter+=1
            listElems=nestedList[nc]+listElems
        else:nonListElems.append(nestedList[nc])  
    if nestedListCounter==0: return (nestedList)
    else:
        nestedList=listElems+nonListElems 
        return list_flattener(nestedList)
请参见下面的示例:

>>> nestedList=['arash',[[1,'anotherOne',[12,'stringX',['kave']]], 'stringY']]
>>> list_flattener(nestedList)
['kave', 12, 'stringX', 1, 'anotherOne', 'stringY', 'arash']

谢谢这可能是一个愚蠢的澄清,但你有一个如何联合它的建议吗<代码>>>>itertools.chain([[“垃圾”[“嵌套的东西”],[],[[[]]]])我通常使用列表(iterable)来联合它,但如果我在这种情况下这样做,我将得到一个非平面列表!联合?我真的不确定那是什么意思<代码>列表(iterable)是从任意iterable中获取列表的最佳方式。使用上面的列表,我可以得到:
>>>列表(itertools.chain([[“垃圾”,“嵌套的东西],[],[],[],[[[]]]])
扁平化()
相比,扁平化()
[“垃圾”,“嵌套的东西”]
chain()
将iterable作为每个参数,如果要传入iterable,请使用
chain.from\u iterable()
。请注意,它将(如回答中所述)仅移除一层嵌套。除此之外,制作一个通用工具并不真正值得,因为不同的情况会将不同的iterables视为需要展平的对象(例如字符串)。对不起,我可能还没有理解它:
>>列表(itertools.chain.from_iterable([[“垃圾”,“嵌套的东西],[],[]]])
给了我
[“垃圾”,“嵌套的东西],[],[],[]]
-1-对列表和元组进行类型检查会使这一点变得非常不灵活。@Lattyware的问题是:“建议用什么方法展平嵌套列表…”@Lattyware对第二个选项有何评论?对不起,我是在回答我自己的问题。我的问题是Python是一种灵活的语言,而类型检查通常是一种糟糕的解决方案。询问者可能只考虑列表,但在某些情况下使用一些自定义数据结构,其功能类似于列表,但不能与代码一起使用。Python是为duck类型设计的,因此,尽管有其他类型的功能,但只适用于某些类型的函数非常烦人,而且通常是一个坏主意。我非常确定
Sequence
需要定义
\u len\u()
,而且可能会测试它的可伸缩性。构建这样的列表是一个非常糟糕的解决方案,生成器会更合适。我会说“非常糟糕的解决方案”有点强。如果嵌套列表相对较小,则生成生成器的速度可能较慢。这取决于需要。我把两者都贴了出来。在一个小列表上创建生成器可能会慢一些,但是当它很小的时候,时间差就无关紧要了。然而,当它很大的时候,它很可能就足够了。不管怎样,最好只使用生成器,这样更容易阅读。除此之外,
hasattr(e,“\uuuuu iter”
通常是一种更好的检查方法,使用
Iterable
ABC进行检查-这样可读性更强。我开始非常喜欢funcy。谢谢你的提示。