如何在不分割字符串的情况下 flatten 列表?

26 投票
7 回答
8137 浏览
提问于 2025-04-16 13:35

我想把可能包含其他列表的列表“压平”,但又不想把字符串拆开。举个例子:

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

我想要的结果是

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

7 个回答

2

一种简单粗暴的方法是把这个字符串放进一个自己的列表里,然后使用 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']
9

这是对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)
34

解决方案:

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

Python 2.x 的旧版本:

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

(在 Python 2.x 中,字符串没有 __iter__ 这个属性,这和 Python 中其他大多数可迭代对象不一样。不过要注意,在 Python 3 中,字符串是有这个属性的,所以上面的代码只适用于 Python 2.x。)

撰写回答