跟踪字符串中字符迭代的列表

时间:2016-03-11 20:18:01

标签: python list iteration encoder

我正在编写一个编码器,我想保留一个列表来跟踪字符串中字符的迭代。

例如:

Input = aaabccccaa
Output = [3, 1, 4, 2]

这就是我所拥有的:

def numberCheck(string, numberList):
    teller = 1
    for i in range(len(string)):
        for j in range(i + 1,len(string)):
            if string[i] == string[j]:
                teller += 1
            else:
                break
        numberList.append(teller)
        teller = 1
    return numberList

但是这给了我输出[3, 2, 1, 1, 4, 3, 2, 1, 2, 1]

我知道为什么这是输出,但我不知道如何修复代码,以便我有我想要的输出。

提前致谢

4 个答案:

答案 0 :(得分:4)

您可以使用内置itertools执行此任务(特别是groupby),而不是您拥有的长函数。

>>> from itertools import groupby
>>> Input = "aaabccccaa"
>>> [len(list(group)) for key, group in groupby(Input)]
[3, 1, 4, 2]

如果你想在字符串中保留字母,数量及其出现顺序:

>>> [{k: len(list(group))} for key, group in groupby(Input)]
[{'a': 3}, {'b': 1}, {'c': 4}, {'a': 2}]

答案 1 :(得分:2)

不要为每个字母创建一个新循环,只需在外循环中将计数器重置为1即可。此外,您不应将数字列表传递给该函数;它应该定义自己的:

def numberCheck(string):
    if not string:
        return []
    numberList = []
    current = string[0]
    i = 0 
    for char in string:
        if char == current:
            i += 1
        else:
            current = char
            numberList.append(i)
            i = 1 
    numberList.append(i)
    return numberList

答案 2 :(得分:1)

我认为安迪拥有"权利"回答意味着它简洁易读。如果你关心时间,这大约要快25%。

from itertools import groupby

string = "aaabccccaa"
print [sum(1 for _ in group) for _, group in groupby(string)]
# [3, 1, 4, 2]

如果你真的关心时间,那么zondo的解决方案比这快50%。 10,000次运行的近似基准:

me:    543 ms
andy:  746 ms
zondo: 286 ms

这是在Python 2.7上完成的。

编辑:看起来Andy的版本在Python 3.4上更快:

me:    611
andy:  461
zondo: 254

答案 3 :(得分:0)

你的外循环在每个角色处开始内循环。你需要你的外部循环向前移动到下一个不同角色的块,而不是下一个。

要解决此问题,请使用相同的算法,使用while循环,以便您可以调整循环控制变量i的推进量:

def numberCheck(string):
    numberList = []
    teller = 1
    i = 0
    while i < len(string):
        for j in range(i + 1,len(string)):
            if string[i] == string[j]:
                teller += 1
            else:
                break
        numberList.append(teller)
        i += teller  # advance by the number of characters you just counted
        teller = 1
    return numberList

或者只使用一个循环和一个条件(带有一些局部变量)来确定何时执行不同的操作。 (更新:请参阅zondo对此代码的回答)

(我是描述性的而不是提供代码,因为这似乎是一个家庭作业问题)