使用functools的替代方法.带有字符串方法的部分



对我的代码的分析显示,str对象的splitstrip方法是调用最多的函数之一。

我使用了这样的结构:

with open(filename, "r") as my_file:
    for line in my_file:
        fields = line.strip("n").split("t")

一些应用了此命令的文件有很多行。

所以我尝试使用"避免点"的建议https://wiki.python.org/moin/PythonSpeed/PerformanceTips如下:

from functools import partial
split = str.split
tabsplit = partial(split, "t")
strip = str.strip
endlinestrip = partial(strip, "n")
def get_fields(tab_sep_line):
    return tabsplit(endlinestrip(tab_sep_line))
with open(filename, "r") as my_file:
    for line in my_file:
        fields = getfields(line)

然而,这给了我get_fields函数的return行一个ValueError: empty separator

经过调查,我所理解的是split方法的分隔符是第二个位置参数,第一个是字符串对象本身,这使得functools.partial"t"理解为要分割的字符串,而我使用"n".strip(tab_sep_line)的结果作为分隔符。因此出现了错误。

你建议怎么做呢?


编辑:我尝试比较三种实现get_fields函数的方法。

方法1:使用纯.strip.split

def get_fields(tab_sep_line):
    return tab_sep_line.strip("n").split("t")

方法2:使用lambda

split = str.split
strip = str.strip
tabsplit = lambda s : split(s, "t")
endlinestrip = lambda s : strip(s, "n")
def get_fields(tab_sep_line):
    return tabsplit(endlinestrip(tab_sep_line))

方法3:使用Jason S提供的答案

split = str.split
strip = str.strip
def get_fields(tab_sep_line):
    return split(strip(tab_sep_line, "n"), "t")

Profiling表示get_fields的累计时间如下:

方法1:13.027

方法2:16.487

方法3:9.714

因此,避免点会有所不同,但使用lambda似乎适得其反。

对于性能"避免点"的建议是(1)只有当你确实有性能问题时才应该这样做,即不是如果它只是被调用了很多次,而是如果它实际上花费了太多时间,并且(2)不会通过使用partial来解决。

点比局部变量花费更多时间的原因是python每次都必须执行查找。但是如果使用partial,那么每次都有一个额外的函数调用,每次都复制和更新一个字典,并且添加两个列表。你没有得到,你在失去。

然而,如果你真的想,你可以这样做:

strip = str.strip
split = str.split
...
fields = split(strip(line), 't')

最新更新