提前设置lambda函数的一部分以避免重复代码

时间:2016-08-07 14:07:23

标签: python python-3.x

以下排序方法完美无缺。

def sort_view_items(self):

    cs = self.settings.case_sensitive

    if self.settings.sort_by_file_name:
        sk = lambda vi: (vi.name if cs else vi.name.lower(), vi.group, vi.tab)

    elif self.settings.sort_by_folder:
        sk = lambda vi: (vi.folder, vi.name if cs else vi.name.lower())

    elif self.settings.sort_by_syntax:
        sk = lambda vi: (vi.syntax, vi.name if cs else vi.name.lower())

    elif self.settings.sort_by_indexes:
        sk = lambda vi: (vi.group, vi.tab)

    self.view_items.sort(key = sk)

然而,lambdas vi.name if cs else vi.name.lower()的区分大小写的相关部分被使用了3次,这让我重复的代码基因变得烦恼。

出于兴趣,可以预先设置案例方面,但是不对name属性进行永久性更改,或者在view_items列表的临时副本中进行更改吗?

例如我尝试在lambda中使用lambda,我认为它不会起作用,猜猜是什么,它没有。虽然意外地接受了语法(没有例外),但它并没有导致实际执行任何排序。

def sort_view_items(self):

    cs = self.settings.case_sensitive

    name_lambda = lambda vi: vi.name if cs else vi.name.lower()

    if self.settings.sort_by_file_name:
        sk = lambda vi: (name_lambda, vi.group, vi.tab)

    ...

3 个答案:

答案 0 :(得分:5)

您需要实际拨打name_lambda

sk = lambda vi: (name_lambda(vi), vi.group, vi.tab)

在您的代码段中,name_lambda已正确定义,但永远不会被调用。

答案 1 :(得分:5)

这要求您向类中添加一个新属性“lower_name”,但是这一更改可让您极大地简化其余代码。

from operator import attrgetter

class Things(object):
    @property
    def lower_name(self):
        return self.name.lower()

    def sort_view_items(self):
        name_field = "name" if self.settings.case_sensitive else "lower_name"

        if self.settings.sort_by_file_name:
            fields = (name_field, "group", "tab")
        elif self.settings.sort_by_folder:
            fields = ("folder", name_field)
        elif self.settings.sort_by_syntax:
            fields = ("syntax", name_field)
        elif self.settings.sort_by_indexes:
            fields = ("group", "tab")

        self.view_items.sort(key=attrgetter(*fields))

答案 2 :(得分:1)

由于您希望在4个条件中的3个条件中使用它,拒绝此重复的最佳方法是计算if条件顶部的名称。此外,您可以使用def关键字正确创建key函数,并返回相应的值,而不是每次都定义一个函数。在这种情况下,您可以将vi传递给key_func并计算此函数顶层的name

def sort_view_items(self):

    def key_func(vi):
        name = vi.name if self.settings.case_sensitive else vi.name.lower()
        if self.settings.sort_by_file_name:
            return name(vi), vi.group, vi.tab

        elif self.settings.sort_by_folder:
            return vi.folder,name(vi)

        elif self.settings.sort_by_syntax:
            return vi.syntax, name(vi)

        elif self.settings.sort_by_indexes:
            return vi.group, vi.tab

    self.view_items.sort(key=key_func)