Python2.7:基于Pythonic方式的模式从列表中提取切片

时间:2016-12-02 23:36:18

标签: python python-2.7 list list-comprehension

我在列表中有大量数据。该列表由短字符串组成。在列表中,隐藏了与特定模式匹配的长度为5的切片:

[<date>, <date>, <4 digit integer>, <string>, <$ amount>]

如何从数据集中提取这些切片?它们可以出现在任何位置(因此它们的索引不能保证是5的倍数)并且散布着可以与模式的一部分匹配的其他数据(也是字符串)。

我从类似的东西开始:

for item in data:
    if re.search(<date pattern>, item):
        if not date1:
            date1 = item
        else:
            date2 = item
    if re.search(<4 digit integer pattern>, item):
        if date1 and date2 and not fourdigit:
            fourdigit = item
        else:
           date1 = None
           date2 = None
    ....

但这非常复杂,容易出错,而且根本不是pythonic。

下一个方法是从数据列表中提取5个项目的滑动窗口,并检查所有项目是否与其模式匹配。如果不是,则将索引增加1(即将窗口滑动1)并检查下一个切片。如果模式匹配,则保存切片,并将索引增加5.类似于:

index = 0
while index < (len(data)-5):
    sliceof5 = data[index:index+5]
    if slice_matches_pattern(sliceof5):
        matching_items.append(sliceof5)
        index += 5
    else:
        index += 1

这种方法很容易实现,并且在以前的解决方案中不易出错,但似乎也不是非常pythonic。

是否可以使用列表理解来完成此操作?类似的东西:

matching_items = [ sliceof5 if slice_matches_pattern(sliceof5) for sliceof5 in data ]

但是,如何让列表理解中的for有时会跳过前进1,有时会前进5。

是否有其他的pythonic方法可以实现这一目标?

1 个答案:

答案 0 :(得分:2)

你的第二个解决方案似乎很好。我会将其更改为生成器(yield您找到的切片),但不能更多。

但是,通过在切片的第2项中查找日期,您可以使其运行得更快。如果它不是日期,您可以向索引添加两个。

当然,如果你可以将所有内容都变成一个与你的整个模式相匹配的正则表达式,那么你会做得更好。