【问题标题】:List Comprehension Method Optimisation列表理解方法优化
【发布时间】:2015-10-18 20:10:33
【问题描述】:

我开发了一些 Python 代码,它们围绕两个自定义类 - 一个“库”类 (Lib),其中包含基于“Cas”类的多个对象的 Python 列表。我没有在这里发布这两个类的代码,但你真正需要知道的是理解我的问题是“库”对象包含一个 Python 列表,“Cas”对象包含各种属性,其中一些是字符串,有些是值。

代码的目标之一是在库类中操作 Python 列表,并根据一些用户驱动的标准返回“Cas”对象的子集。例如,返回特定属性等于给定字符串或大于给定值的 Cas 对象。

为此,我编写了以下泛型方法filterLibrarySingle,以允许我根据各种方法(filterMethod)、属性(filterField)和值(filterValue)过滤库类(self.Lib)中的Python列表。在方法中,我使用列表推导来实现这一点。

在分析我的代码时,这种方法似乎有点瓶颈!有人知道如何加快速度吗?

def filterLibrarySingle(self, filterField, filterMethod, filterValue1, filterValue2=None):
    if filterMethod == 'eq':
        self.Lib = [cas for cas in self.Lib if getattr(cas, filterField) == filterValue1]

    elif filterMethod == 'lt':
        self.Lib = [cas for cas in self.Lib if getattr(cas, filterField) < filterValue1]

    elif filterMethod == 'gt':
        self.Lib = [cas for cas in self.Lib if getattr(cas, filterField) > filterValue1]

    elif filterMethod == 'le':
        self.Lib = [cas for cas in self.Lib if getattr(cas, filterField) <= filterValue1]

    elif filterMethod == 'ge':
        self.Lib = [cas for cas in self.Lib if getattr(cas, filterField) >= filterValue1]

    elif filterMethod == 'gelt':
        self.Lib = [cas for cas in self.Lib if  getattr(cas, filterField) >= filterValue1 and getattr(cas, filterField) < filterValue2]

    elif filterMethod == 'gele':
        self.Lib = [cas for cas in self.Lib if  getattr(cas, filterField) >= filterValue1 and getattr(cas, filterField) <= filterValue2]

我为此绞尽脑汁想加快速度,但我想我的 Python 知识还不够好!

我希望有人能够帮助提高这种方法的性能。

非常感谢

标记

【问题讨论】:

  • 你可能会发现 dict 比所有那些 elifs 更好
  • 你能举个例子吗?
  • 我怀疑如果这个 fn 是您的程序的瓶颈,那么问题实际上不在于它是如何编写的,而在于它在您的应用程序中被调用了多少次。
  • 你可能就在那儿……可以调用好几次
  • 再看,它被调用了好几次,但在时间/命中方面似乎仍然是瓶颈

标签: python performance list-comprehension itertools


【解决方案1】:

加速此类处理的常用方法是消除纯 python 步骤,转而支持基于高速 C 的工具,包括 functools.partial()itertools.imap()itertools.ifilter()operator.__eq__() 和 @987654325 @。

【讨论】:

    【解决方案2】:

    算子库已经定义了所有这些函数,因此可以更简单地重写。

    import operator
    def filterLibrarySingle(self, filterField, filterMethod, filterValue1, filterValue2=None):
        self.Lib = [cas for cas in self.Lib
                    if operator.__dict__[filterMethod](getattr(cas, filterField),filterValue1)]
    

    但它没有geltgele
    所以你可能需要创建一个字典:

    filter_methods = {
        'le': operator.le,
        ...
        'gelt': lambda a, b, c: a >= b and a < c
        'gele': lambda a, b, c: a >= b and a <= c
    }
    
    def filterLibrarySingle(self, filterField, filterMethod, filterValue1, filterValue2=None):
        if filterMethod in ['gelt', 'gele']:
            self.Lib = [cas for cas in self.Lib
                        if filter_methods[filterMethod](getattr(cas, filterField), filterValue1, filtervalue2)]
        else:
            self.Lib = [cas for cas in self.Lib
                        if filter_methods[filterMethod](getattr(cas,  filterField), filterValue1)]
    

    但是,这些都不会影响您的应用程序的性能,您需要查看您拥有的逻辑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-27
      • 1970-01-01
      • 2021-08-26
      • 2012-02-02
      • 2014-07-18
      • 1970-01-01
      • 2017-07-06
      • 1970-01-01
      相关资源
      最近更新 更多