【发布时间】:2017-04-17 23:18:22
【问题描述】:
我的列表中有大量数据。该列表由短字符串组成。列表中隐藏了与特定模式匹配的长度为 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 方法来实现这一点?
【问题讨论】:
-
我的第一直觉是使用
re可靠地匹配每个字符串,并使用列表推导或循环将其应用于列表中的所有字符串。另一种选择是将所有字符串连接成一个大字符串(或字符串块)并使用更全面的re匹配器(多行?) -
我得到的第二个建议(尤其是在看到@double_j 的答案之后)。我没有得到您的第一个建议,尤其是列表理解部分。例如,一行中可能有 3 个日期,其中只有最后两个日期可以成为我正在寻找的整体模式的一部分。以及如何匹配 5 个模式的序列?在列表理解过程中,您必须以某种方式“记住”您从列表中拉出的项目。
标签: python python-2.7 list list-comprehension