检查一行是否以列表中的字符串开头的首选方法?

时间:2015-12-02 08:22:05

标签: python string performance python-3.x for-loop

我正在尝试逐行对文件进行排序,将开头与列表中的字符串进行比较,如下所示:

for line in lines:
    skip_line = True
    for tag in tags:
        if line.startswith(tag) is False:
            continue
        else:
            skip_line = False
            break
    if skip_line is False:
        #do stuff

虽然代码工作得很好,但我想知道是否有更简洁的方法来检查这种情况。我查看了any(),但它似乎只是让我有可能检查我的行是否以固定标记开头(不会消除循环遍历列表所需的for循环。

所以,基本上我问这个:
是否有比使用for循环迭代tags列表以检查当前行是否以其中一个元素开头的更好,更时尚的选项?

正如Paradox在答案中指出的那样: 使用字典来查找字符串是否存在具有O(1)复杂度并且实际上使整个代码看起来更清晰,同时比循环遍历列表更快。像这样:

tags = {'ticker':0, 'orderBook':0, 'tradeHistory':0}
for line in lines:
    if line.split('\t')[0] in tags:
        #do stuff

5 个答案:

答案 0 :(得分:2)

如果你决定把它拉成单线,你可以使用发电机:

tagged_lines = (line for line in lines if any(line.startswith(tag) for tag in tags))
for line in tagged_lines:
    # Do something with line here 

当然,这是多么可读是一个不同的问题。

您之前可能会看到类似[x*x for x in range(10)]的语法,但通过交换[] (),我们只会在要求时生成每个项目。

答案 1 :(得分:1)

您可以将所有标记放在HashMap中,并执行简单的查找,例如myMap.exists(“word”),而不是迭代标记列表。迭代标记列表并以O(1)复杂度工作会更快。在python中它实际上是一个字典数据结构。 http://progzoo.net/wiki/Python:Hash_Maps

答案 2 :(得分:0)

以前曾经问过这个问题。看一下这篇文章,了解更多解决方案。我会将这篇文章标记为重复,但我仍然没有声誉。

https://stackoverflow.com/a/10477481/5016492

您需要修改正则表达式,以便查看该行的开头。像这样的东西应该适合你'^ tag'。

答案 3 :(得分:0)

事实上any()将完成这项工作

循环每一行

for line in lines:
     tagged = any(lambda: line.startswith(y), tags)

任何列表都以任何标记开头

any(lambda x: any(lambda y: x.startswith(y), tags), lines)

过滤标记的行

filter(lambda x: any(lambda y: x.startswith(y), tags), lines)

答案 4 :(得分:0)

如本例中的any()和filter()组合怎么样:

# use your data here ...
mytags = ('hello', 'world')
mylines = ('hello friend', 'you are great', 'world is cruel')

result = filter(lambda line: any(map(lambda tag: line.startswith(tag), mytags)), mylines)
print result