如何在不拆分字符串的情况下展平列表?

时间:2011-03-13 00:15:27

标签: python

我想整理可能包含其他列表的列表,而不会破坏字符串。例如:

In [39]: list( itertools.chain(*["cat", ["dog","bird"]]) )
Out[39]: ['c', 'a', 't', 'dog', 'bird']

我希望

['cat', 'dog', 'bird']

6 个答案:

答案 0 :(得分:21)

def flatten(foo):
    for x in foo:
        if hasattr(x, '__iter__'):
            for y in flatten(x):
                yield y
        else:
            yield x

(字符串很方便地实际上没有__iter__属性,这与Python中几乎所有其他可迭代对象不同。请注意,这在Python 3中有所改变,因此上述代码仅适用于Python 2.x. )

Python 3.x的版本:

def flatten(foo):
    for x in foo:
        if hasattr(x, '__iter__') and not isinstance(x, str):
            for y in flatten(x):
                yield y
        else:
            yield x

答案 1 :(得分:4)

略微修改orip的答案,避免创建中间列表:

import itertools
items = ['cat',['dog','bird']]
itertools.chain.from_iterable(itertools.repeat(x,1) if isinstance(x,str) else x for x in items)

答案 2 :(得分:1)

一种强力方式是将字符串包装在自己的列表中,然后使用itertools.chain

>>> l = ["cat", ["dog","bird"]]
>>> l2 = [([x] if isinstance(x,str) else x) for x in l]
>>> list(itertools.chain(*l2))
['cat', 'dog', 'bird']

答案 3 :(得分:1)

def squash(L):
    if L==[]:
        return []
    elif type(L[0]) == type(""):
        M = squash(L[1:])
        M.insert(0, L[0])
        return M
    elif type(L[0]) == type([]):
        M = squash(L[0])
        M.append(squash(L[1:]))
        return M

def flatten(L):
    return [i for i in squash(L) if i!= []]

>> flatten(["cat", ["dog","bird"]])
['cat', 'dog', 'bird']

希望这有帮助

答案 4 :(得分:1)

使用 reduce 库中的 functools 函数,您可以这样做:

import functools
items = ['cat',['dog','bird']]
print(functools.reduce(lambda a, b: [a] + b, items))

答案 5 :(得分:0)

这是一种单线方法:

[item for sublist in [[item] if type(item) is not list else item for item in list1] for item in sublist]