使用列表解析细分此列表

时间:2012-03-04 22:58:13

标签: python list list-comprehension

我想知道是否有一个好的pythonic方法来打破这个列表:

['1,2,3', '22', '33']

进入列表:

['1','2','3','22','33']

使用列表理解?

7 个答案:

答案 0 :(得分:7)

使用列表理解,它看起来像这样:

>>> L = ['1,2,3', '22', '33']
>>> [x for l in L for x in l.split(",")]
['1', '2', '3', '22', '33']

注意: 有更清晰,更好的方法,正如已经在其他答案中发布的那样(itertools链或生成器表达式都很好)。但是由于问题是关于列表理解语法的问题,我认为无论如何我都会将其写入。

答案 1 :(得分:5)

由于已经使用sum()函数作为解决方案发布了两个答案,我认为我将使用itertools.chain提供更多方法

from itertools import chain
x = ['1,2,3', '22', '33']
result = chain.from_iterable(i.split(',') for i in x)

print result
#<itertools.chain object at 0x1004b5e10>

链命令的结果是生成器。所以你可以遍历结果,或者把它转换成另一个序列类型(元组,列表,集合......)

答案 2 :(得分:5)

我不会使用sum,因为它会重复连接并创建大量副本。我会这样做:

>>> import itertools
>>> l =  ['1,2,3', '22', '33']
>>> list(itertools.chain.from_iterable(s.split(',') for s in l))
['1', '2', '3', '22', '33']

对于非常短的列表来说,它确实有点慢:

>>> %timeit sum((s.split(',') for s in l), [])
100000 loops, best of 3: 2.38 us per loop
>>> %timeit list(itertools.chain.from_iterable(s.split(',') for s in l))
100000 loops, best of 3: 3.51 us per loop

但对于长列表,它比使用sum更快方式

>>> l =  ['1,2,3', '22', '33'] * 500
>>> %timeit sum((s.split(',') for s in l), [])
100 loops, best of 3: 6.22 ms per loop
>>> %timeit list(itertools.chain.from_iterable(s.split(',') for s in l))
1000 loops, best of 3: 664 us per loop

实际上,我更喜欢wim的回答。快速测试显示它在所有情况下都是最快的:

>>> l =  ['1,2,3', '22', '33'] 
>>> %timeit [x for s in l for x in s.split()]
1000000 loops, best of 3: 1.45 us per loop
>>> l =  ['1,2,3', '22', '33'] * 500
>>> %timeit [x for s in l for x in s.split()]
1000 loops, best of 3: 559 us per loop

答案 3 :(得分:3)

打破你的问题。你永远不会看到如何一次解决整个问题,而Python从来没有简单的内置解决方案来处理整个问题。找出问题最基本的部分,每个部分通常都有简单的直接解决方案。然后结合解决方案。另外,不要指望你可以在问题上挥动一个像“列表理解”这样的神奇口号来让它消失。弄清楚你的解决方案需要做什么,然后考虑列表理解能否做到这一点。

你有一个字符串'1,2,3'。您需要将其拆分为多个字符串的列表,其中包含以逗号分隔的原始字符串的位:

>>> help(str.split)
Help on method_descriptor:

split(...)
    S.split([sep [,maxsplit]]) -> list of strings

    Return a list of the words in the string S, using sep as the
    delimiter string.  If maxsplit is given, at most maxsplit
    splits are done. If sep is not specified or is None, any
    whitespace string is a separator and empty strings are removed
    from the result.

>>> '1,2,3'.split(',')
['1', '2', '3']
>>> '3'.split(',')
['3']

现在,您有一个字符串列表,并且您希望将它们分成如上所示的列表:

>>> [s.split(',') for s in ['1','2','3','22','33']]
[['1'], ['2'], ['3'], ['22'], ['33']]

现在你已经有了一份清单清单。您需要一个包含列表列表中每个列表元素的列表。操作“给我列表列表中的每个列表中的每个东西”相当自然地映射到列表理解,如下所示:

>>> list_of_lists = [[1, 2, 3], ['a', 'b', 'c']]
>>> [thing for alist in list_of_lists for thing in alist]
[1, 2, 3, 'a', 'b', 'c']

全部放在一起:

>>> [bit for string in ['1','2','3','22','33'] for bit in string.split(',')]
['1', '2', '3', '22', '33']

这就是你如何使用列表推导来解决这个问题。在其他答案中还有许多其他可能的解决方案,这些解决方案在技术方面更好。但是如果你是Python的新手,那么学习整个标准库(特别是像itertools这样强大而又抽象的东西)会很困难,并且你觉得不必这么做。从长远来看,熟悉基础知识将为您提供更多服务。

答案 4 :(得分:2)

这是我能想到的最简单的解决方案。

它正在使用带有生成器表达式的sum(),因为您实际上并不需要保留创建的子列表。

>>> a = ['1,2,3', '22', '33']
>>> sum((s.split(',') for s in a), [])
['1', '2', '3', '22', '33']

答案 5 :(得分:1)

你可以这样做(假设你的名单叫做l):

sum([s.split(',') for s in l], [])

答案 6 :(得分:1)

一种简单的方法是:

>>> lst = ['1,2,3', '22', '33']
>>> res = []
>>> for x in lst:
...     res.extend(x.split(','))
>>> res
['1', '2', '3', '22', '33']

虽然它没有使用列表理解,但我不明白为什么你会在这种情况下使用它。