【问题标题】:Alternatives to using functools.partial with string methods [duplicate]将 functools.partial 与字符串方法一起使用的替代方法 [重复]
【发布时间】:2014-10-02 22:10:36
【问题描述】:

我的代码分析表明,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")

方法二:使用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")

分析表明get_fields 的累积时间如下:

方法 1:13.027

方法 2:16.487

方法 3:9.714

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

【问题讨论】:

  • 如果它真的很重要,那么值得摆脱 get_fields() 并在循环中内联表达式。

标签: python string performance arguments partial


【解决方案1】:

关于性能“避免点”的建议是(1)只有当你确实有性能问题时才应该做的事情,即如果它只是被调用很多次但如果它实际上需要太多时间 ,以及 (2) 使用partial 无法解决。

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

但是,如果你真的想要,你可以这样做:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-13
    相关资源
    最近更新 更多