Python不规则循环

时间:2016-01-23 13:02:49

标签: python

我正在寻找一种优雅的“Pythonic”方式来循环输入一定大小的组。但是组的大小各不相同,在开始解析之前,您不知道特定组的大小。

实际上我只关心两种尺寸的团体。我有一个很大的输入序列,它们大多是大小为X但偶尔大小为Y.对于这个例子,我们说X = 3和Y = 4(我的实际问题是X = 7和Y = 8)。我不知道直到元素组中间,如果它将是一组大小为X或大小为Y的元素。

在我的问题中,我正在处理输入行,但为了简化,我将用字符说明。

因此,如果它是一个特定大小的组,我知道我将始终以相同的顺序获得输入。因此,例如,如果它是一个X大小的组,我将获得[a,a,b]类型的元素,但如果它是一个大小Y组,我将获得类型[a,a,c,b]的元素。这是'a'类型的某种东西我想以某种方式处理它而'b'是另一种类型。

显然,我必须在某个时刻测试一个元素,以确定它是第一类还是另一组。如上所示,我不能只检查每个元素的类型,因为顺序可能有两个相同的元素。这些组在开始时可以是相同的模式,并且仅在结束时不同。在这个例子中,我最早可以通过测试第三个元素(看看它是'c'类型还是键入'b')来检查我是否在大小为X或大小为Y的组中。

我有一个带有暴露索引和两个额外变量的for循环的解决方案,但我想知道是否有更优雅的解决方案。

这是我的代码。我将pass语句放在我实际解析的位置,具体取决于它的类型:

counter = 0
group = 3
for index, x in enumerate("aabaabaacbaabaacbaabaab"):
    column = index - counter;
    print(str(index) + ", " + x + ", " + str(column))

    if column == 0:
        pass
    elif column == 1:
        pass
    elif column == 2:
        if x == 'c':
            pass
        elif x == 'd':
            group = 4
    elif column == 3:
        pass

    if column + 1 == group:
        counter += group 
        group = 3

在代码示例中,输入流为aabaabaacbaabaacbaabaab,因此它是以下组:

  1. aab(3)
  2. aab(3)
  3. aacb(4)
  4. aab(3)
  5. aacb(4)
  6. aab(3)
  7. aab(3)

3 个答案:

答案 0 :(得分:4)

我会使用一个收集这些组的生成器并确定每个组的大小,然后最终产生每个组:

def getGroups (iterable):
    group = []
    for item in iterable:
        group.append(item)
        if len(group) == 3 and group[2] == 'c':
            yield group
            group = []
        elif len(group) == 4 and group[2] == 'd':
            yield group
            group = []

for group in getGroups('abcabcabdcabcabdcabcabc'):
    print(group)
['a', 'b', 'c']
['a', 'b', 'c']
['a', 'b', 'd', 'c']
['a', 'b', 'c']
['a', 'b', 'd', 'c']
['a', 'b', 'c']
['a', 'b', 'c']

答案 1 :(得分:2)

看起来你需要一个带回溯的简单自动机,例如:

#include <iostream>
#include <string>
#include <time.h>
std::string current_date();
std::string current_time();
int main(){
    std::cout<<"Current date => "<<current_date()<<"\n";
    std::cout<<"Current time => "<<current_time()<<"\n";
}
std::string current_date(){
    time_t now = time(NULL);
    struct tm tstruct;
    char buf[40];
    tstruct = *localtime(&now);
    //format: day DD-MM-YYYY
    strftime(buf, sizeof(buf), "%A %d/%m/%Y", &tstruct);
    return buf;
}
std::string current_time(){
    time_t now = time(NULL);
    struct tm tstruct;
    char buf[40];
    tstruct = *localtime(&now);
    //format: HH:mm:ss
    strftime(buf, sizeof(buf), "%X", &tstruct);
    return buf;
}

答案 2 :(得分:0)

使用您的特定示例,您可以使用正则表达式:

def parser(string, patterns):
    patterns=sorted(patterns, key=len, reverse=True)
    i=0
    error=False
    while i<len(string) and not error:
        for pat in patterns:
            j=len(pat)
            if string[i:i+j]==pat:
                i+=j
                yield pat
                break
        else:
            error=True

    if error or i<len(string):
        raise SyntaxWarning, "Did not match the entire string"

>>> list(parser(s, ['aab', 'aacb']))
['aab', 'aab', 'aacb', 'aab', 'aacb', 'aab', 'aab']

如果你想要一个做同样事情的解析器,你可以这样做:

xp_cmdshell