这个用于排序数字的lambda如何工作?

时间:2017-05-29 09:37:44

标签: python python-2.7 sorting lambda

#code for sorting big integers
lis = ['234', '5', '2', '12435645758']

lis.sort(key = lambda x: len(x))
print lis
#output ['5', '2', '234', '12435645758']

lis.sort(key = lambda x: (len(x), x))
print lis
#output ['2', '5', '234', '12435645758']

我试图在Python中对大数字字符串进行排序而不将字符串转换为整数,并且无法理解如何评估这些lambda表达式。

第一个lambda表达式是根据字符串的长度进行排序并对列表进行排序,但第二个表达式是做什么的?我想知道如何评估第二个lambda表达式。

2 个答案:

答案 0 :(得分:2)

lambda为列表中的每个值返回一个元组。然后使用这些元组来通知排序顺序。因此,不要将'234''5'进行比较,而是要求排序算法比较(3, '234')(1, '5')

Python对元组lexicographically进行排序,也就是说,首先比较两个元组的第一个元素,然后如果它们相同,继续比较第二个元素等,直到没有元素为止比较。

因为元组同时包含长度和字符串本身,对于相等长度的字符串,字符串接下来按其实际值排序。这会在末尾放置较长的字符串,在前面放置较短的字符串,在每组等长内放置,字符串按其值排序。

再次查看您的输入示例,对于'234''5',生成的元组(3, '234')(1, '5')具有不相等的第一个元素,因此(1, '5')之前已排序(3, '234')。但是对于'5''2',生成的元组是(1, '5')(1, '2')(两个都是1个字符长),这些元组的第一个元素是相等的。因此,它们会在第二个元素上进行排序,将'2'放在'5'之前。

如果没有这样的断路器(因此密钥相等),Python会保留相对顺序。对于您的第一个示例,排序键仅为len(x),并且由于'5''2'具有相同的长度,并且没有其他可比较它们,因此Python将它们放入输出中相同的相对顺序,'5'之前的'2'

答案 1 :(得分:1)

元组,列表和字符串比较他们的"Lexicographical order (Wikipedia link)"。这意味着他们从左边开始比较相等的元素。只要一个元素不相等,它们就会比较该元素是小于还是大。

在第二个sort中,您创建一个包含长度,然后是字符串的元组。因此,如果您比较两个元素,它将检查:如果长度不相等,则较短的元素将被视为“较小”。如果长度相等,则较低“字符串表示”的数字为“较小”。

这大致相当于首先按长度排序,然后按字符串表示排序:

lis = ['234', '5', '2', '12435645758']

class StringInteger(object):
    def __init__(self, string):
        self.string = string

    def __lt__(self, other):   
        """ that's the method that implements "smaller than": < comparisons."""
        # check if the lengths are equal
        if len(self.string) == len(other.string):
            # lengths are equal, so compare the strings
            return self.string < other.string
        else:
            # lengths are not equal, compare the lengths
            return len(self.string) < len(other.string)

sorted(lis, key=StringInteger)  # ['2', '5', '234', '12435645758']