1

我有一堆字符串通过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

4 回答 4

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+|.')
于 2013-05-14T01:24:39.923 回答
7

我会使用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使用键函数将序列拆分为连续的组。在这种情况下,我的 keyfunction 是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', '!']
于 2013-05-14T01:22:55.120 回答
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', '!']
于 2013-05-14T02:08:32.583 回答
0

冒着因使用 c 风格的解决方案(而不是 pythonic 列表组合)而被否决的风险,这里有一个易于阅读的解决方案:

>>> 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 循环执行其操作时,它不会双倍递增,然后外部再次递增。

于 2013-05-14T05:47:11.540 回答