Python:将逗号分隔的字符串直接拆分为一个集合

时间:2016-07-10 20:35:17

标签: python string performance optimization

我有一些代码可以执行以下操作:

if string in comma_delimited_string.split(','):
    return True

This website表示使用集合和dicts进行成员资格测试比使用列表或元组快得多。我知道做set(comma_delimited_string.split(','))不会提高速度,因为列表在被转换为集合之前仍然被创建(或者至少,当我计时时它似乎会减慢它)。

我当时想知道,(主要是出于好奇而不是我的代码的真正好处),有没有办法实现comma_delimited_string.split(',')的相同效果,但直接创建一个集合,而不是列表,具有意图加快上述行动?

3 个答案:

答案 0 :(得分:5)

你忽略了这样一个事实:为了将任何东西转换为集合,你需要迭代它。并且该迭代与您搜索原始列表时已经完成的完全相同。所以这样做没有任何好处,只是开销。

如果您多次执行此操作,则搜索集合会更有效,因为这样可以分摊转化成本。但转换本身总是线性扫描;没有办法避免这种情况。

答案 1 :(得分:2)

不,str.split操作始终返回一个列表,并尝试将其转换为set将花费时间。编写自己直接生成集合的手工split也会慢一些,因为str.split是在C中实现的(源代码应该在Objects/stringlib/split.h下)

但请注意如果您的string不包含逗号,您希望string不是返回的元素的子字符串split,那么你可以这样做:

if string in comma_delimited_string:

如果string包含逗号,那么您的测试将始终失败(因为根据定义,text.split(',')的元素将永远不会包含一个。

上述情况失败的情况是您有以下情况:

if "a" in "aaa,bb,c".split(',')

因为在这种情况下"a" in ["aaa", "bb", "c"]失败了。

或者你可以使用正则表达式:

import re
if re.search(r'(^{0},)|(,{0},)|(,{0}$)|(^{0}$)'.format(re.escape(string)), comma_delimited_string):

但是我不知道这是否会更快,这可能取决于你的输入。

答案 2 :(得分:1)

虽然对现有集合的成员资格测试可能比列表(O(n))更快(O(1)),但您仍需要从字符串创建集合,该集合将为O(n )。所以关于时间复杂性你无能为力。

您可以通过扫描字符串而不是构建中间数据结构来以恒定因子加速测试:

(',%s,' % string) in (',%s,' % comma_delimited_string)

除非你有充分的理由,否则不要使用它。