迭代列表并连接相同类型的项目

时间:2013-05-14 01:18:19

标签: python string list

我通过list(string)将一堆字符串推入列表:

stringy = "I've 24got a 697love-a-ly2 bunch of 000coconuts!"
listy = list(stringy)

listy的样子:

['I', "'", 'v', 'e', ' ', '2', '4', 'g', 'o', 't', ' ', 'a', ' ', '6', '9'...

我正在寻找一种更简洁的方法来遍历列表,并且不丢弃任何单个字符条目,将所有整数连接在一起产生:

['I', "'", 'v', 'e', ' ', '24', 'g', 'o', 't', ' ', 'a', ' ', '697','l','o'...

整数将在字符串中是不可预测的,并且数字中的位数也是不可预测的(我可以遇到1或1000000000。)

首先要考虑以下内容来查找整数值:

for i in listy:
    if i.isdigit():
        x = listy.index(i)
        z = listy[x+1]
        if z.isdigit():

......但这只是一个低效的血腥混乱。

实际上将这些数字放在一起会非常容易,但我无法想出一个简洁的方法来检查每个数字。有什么建议吗?

4 个答案:

答案 0 :(得分:10)

您可以使用re

完成此操作
>>> import re
>>> a = "I've 24got a 697love-a-ly2 bunch of 000coconuts!"
>>> re.findall(r'\d+|.', a)
['I', "'", 'v', 'e', ' ', '24', 'g', 'o', 't', ' ', 'a', ' ', '697', 'l', 'o', 'v', 'e', '-', 'a', '-', 'l', 'y', '2', ' ', 'b', 'u', 'n', 'c', 'h', ' ', 'o', 'f', ' ', '000', 'c', 'o', 'c', 'o', 'n', 'u', 't', 's', '!']

如果您多次执行此操作,则应考虑将其编译为

>>> splitter = re.compile(r'\d+|.')

答案 1 :(得分:6)

我会使用itertools.groupby(免责声明:我将它用于所有事情......)

>>> from itertools import groupby, count
>>> tick = count()
>>> [''.join(group) for key, group in groupby(sy, lambda c: c.isdigit() or next(tick))]
['I', "'", 'v', 'e', ' ', '24', 'g', 'o', 't', ' ', 'a', ' ', '697', 'l', 'o', 'v', 'e', '-', 'a', '-', 'l', 'y', '2', ' ', 'b', 'u', 'n', 'c', 'h', ' ', 'o', 'f', ' ', '000', 'b', 'a', 'l', 'l', 'o', 'o', 'n', 's', '!']

groupby使用键函数将序列拆分为连续的组。在这种情况下,我的键功能是c.isdigit() or c,它将为数字返回True,为非数字返回字符。正如@gnibbler指出的那样,我们需要小心,我们不会意外地合并连续的字符..

第二,我们不需要count技巧:

>>> from itertools import groupby, chain
>>> gg = ([''.join(group)] if key else list(group) for key, group in groupby(sy, str.isdigit))
>>> list(chain.from_iterable(gg))
['I', "'", 'v', 'e', ' ', '24', 'g', 'o', 't', ' ', 'a', ' ', '697', 'l', 'o', 'v', 'e', '-', 'a', '-', 'l', 'y', '2', ' ', 'b', 'u', 'n', 'c', 'h', ' ', 'o', 'f', ' ', '000', 'b', 'a', 'l', 'l', 'o', 'o', 'n', 's', '!']

答案 2 :(得分:0)

另一种方法是从反转列表(或堆栈)中弹出()字符:

>>> groups = []
>>> rlisty = list(reversed(listy))
>>> while rlisty:
    char = rlisty.pop()
    groupedchar = char
    while rlisty: # Look ahead for digits
        # Take next char from rlist
        nextchar = rlisty.pop()
        if nextchar.isdigit():
            groupedchar += nextchar # Group digits together
        else:
            # Put back into list for next loop
            rlisty.append(nextchar)
            break

    groups.append(groupedchar)   

>>> groups
['I', "'", 'v', 'e', ' 24', 'g', 'o', 't', ' ', 'a', ' 697', 'l', 'o', 'v', 'e', '-', 'a', '-', 'l', 'y2', ' ', 'b', 'u', 'n', 'c', 'h', ' ', 'o', 'f', ' 000', 'c', 'o', 'c', 'o', 'n', 'u', 't', 's', '!']

答案 3 :(得分:0)

冒着使用c风格解决方案(而不是pythonic list comps)进行投票的风险,这是一个易于阅读的解决方案:

>>> stringy = "I've 24got a 697love-a-ly2 bunch of 000coconuts!"
>>> x = list(stringy)
>>> i = 0
>>> l = []
>>> while i < len(x):
        t = ''
        while x[i].isdigit():
                t += x[i]
                i += 1
        if t:
                l.append(t)
                i -= 1
        else:
                l.append(x[i])
        i += 1


>>> l
['I', "'", 'v', 'e', ' ', '24', 'g', 'o', 't', ' ', 'a', ' ', '697', 'l', 'o', 'v', 'e', '-', 'a', '-', 'l', 'y', '2', ' ', 'b', 'u', 'n', 'c', 'h', ' ', 'o', 'f', ' ', '000', 'c', 'o', 'c', 'o', 'n', 'u', 't', 's', '!']
>>>

唯一令人困惑的部分可能是i -= 1。那就是那里i当内部while循环完成它时,{{1}}没有得到双递增,然后外部再次递增。