#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表达式。
答案 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']