我知道这听起来很琐碎,但是我没有意识到Python的sort()函数很奇怪。我有一个实际上是字符串形式的“数字”列表,因此,我先将它们转换为int,然后尝试进行排序。

list1=["1","10","3","22","23","4","2","200"]
for item in list1:
    item=int(item)

list1.sort()
print list1


给我:

['1', '10', '2', '200', '22', '23', '3', '4']


我想要的是

['1','2','3','4','10','22','23','200']


我一直在寻找与数字排序相关的一些算法集,但我发现所有这些都涉及对字母数字集进行排序。

我知道这可能是一个没有脑子的问题,但是google和我的教科书没有提供比.sort()函数更多或更少有用的功能。

评论

请注意,您的for循环不会像您认为的那样起作用。

您从未更新过list1。是什么让您认为列表正在更新?

当提供list1 = ['1','1.10','1.11','1.1','1.2']作为输入时,也会出现类似的问题。而不是得到输出[[1],'1.1','1.2','1.10','1.11'],我得到的是['1','1.1','1.10','1.11','1.2' ]

在python 3中,您可能要使用sorted(mylist)

#1 楼

您实际上尚未将字符串转换为int。或更确切地说,您做了,但是随后您对结果什么也没做。您想要的是:

list1 = ["1","10","3","22","23","4","2","200"]
list1 = [int(x) for x in list1]
list1.sort()


如果出于某种原因需要保留字符串而不是整数(通常是个坏主意,但是也许您需要保留前导零或其他内容) ),则可以使用按键功能。 sort采用命名参数key,该参数是在比较每个元素之前对其进行调用的函数。比较键函数的返回值,而不是直接比较列表元素:

list1 = ["1","10","3","22","23","4","2","200"]
# call int(x) on each element before comparing it
list1.sort(key=int)


评论


当我在2.7中尝试key = int时,我什么也没有

– KI4JGT
13年1月28日在5:48

如果list元素存储为“整数”,则此方法有效,在浮点值的情况下应如何处理?例如,list1 = [1、1.10、1.11、1.1、1.2]

–sathish
16年5月19日在9:01



@ KI4JGT的sort方法修改列表并返回None。因此,仅使用list1.sort(key = int)而不是list1 = list1.sort(key = int)即可对list1进行排序。

–乔西亚(Josiah Yoder)
18年6月20日在16:41

@ KI4JGT .sort()是一个就地运算符,它返回None,它对列表进行排序,您可能想使用sorted()

–sherpya
18年11月14日在15:31

#2 楼

您可以将函数传递给key方法的.sort参数。这样,系统将按键(x)而不是x进行排序。

函数

list1.sort(key=int)


或列表理解

list1 = list(map(int, list1))   # you don't need to call list() in Python 2.x


#3 楼

如果要使用sorted()函数:sorted(list1, key=int)

它返回一个新的排序列表。

评论


也可以使用套装!

– M T
5月16日16:11

#4 楼

昨天我也遇到了同样的问题,并找到了一个名为[natsort] [1]的模块,它可以解决您的问题。用途:
from natsort import natsorted # pip install natsort

# Example list of strings
a = ['1', '10', '2', '3', '11']

[In]  sorted(a)
[Out] ['1', '10', '11', '2', '3']

[In]  natsorted(a)
[Out] ['1', '2', '3', '10', '11']

# Your array may contain strings
[In]  natsorted(['string11', 'string3', 'string1', 'string10', 'string100'])
[Out] ['string1', 'string3', 'string10', 'string11', 'string100']

它也适用于字典,相当于sorted
[1]:https://pypi.org/project/natsort/

#5 楼

您还可以使用:

import re

def sort_human(l):
    convert = lambda text: float(text) if text.isdigit() else text
    alphanum = lambda key: [convert(c) for c in re.split('([-+]?[0-9]*\.?[0-9]*)', key)]
    l.sort(key=alphanum)
    return l


这与您可以在互联网上找到的其他东西非常相似,但也适用于[abc0.1, abc0.2, ...]这样的字母数字。

评论


您可能应该返回一个新列表或修改该列表,而不要同时返回两者。上面的代码修改列表,然后返回它。使用sorted()来制作一个新列表。

– Victor Nordam Suadicani
11月17日19:15

#6 楼

Python的排序并不奇怪。只是这段代码:

for item in list1:
   item=int(item)


并没有按照您的想法去做-item并没有被替换回列表中,而是被扔掉了。 />
无论如何,正确的解决方案是使用key=int,就像别人向您展示的那样。

#7 楼

Seamus Campbell的答案不适用于python2.x。使用list1 = sorted(list1, key=lambda e: int(e))功能的lambda效果很好。

#8 楼

尝试此操作,它将按降序对列表进行排序(在这种情况下,无需指定键):

Process

listB = [24, 13, -15, -36, 8, 22, 48, 25, 46, -9]
listC = sorted(listB, reverse=True) # listB remains untouched
print listC


输出:

 [48, 46, 25, 24, 22, 13, 8, -9, -15, -36]


#9 楼

最新的解决方案是正确的。您正在以字符串形式读取解决方案,在这种情况下,顺序为1,然后是100,然后是104,然后是2,然后是21,然后是2001001010,3,依此类推。

您必须以一个int代替:

已排序的字符串:

stringList = (1, 10, 2, 21, 3)

已排序的int:

intList = (1, 2, 3, 10, 21)

要进行转换,只需将stringList放在int(blahblah)内。

再次:

stringList = (1, 10, 2, 21, 3)

newList = int (stringList)

print newList

=> returns (1, 2, 3, 10, 21) 


评论


TypeError:int()参数必须是字符串或数字,而不是'tuple'

– Cees Timmerman
14年4月14日在14:56

另外,stringList中的字符串应带有引号。

–帐篷
15年11月20日在18:01

这是一个让人难以理解的预测:“最新的解决方案是正确的”;)

– GreenAsJade
16-2-29在1:13

#10 楼

如果您想使用数字字符串更好地采用我的代码中所示的另一个列表,它将很好用。

list1=["1","10","3","22","23","4","2","200"]

k=[]    
for item in list1:    
    k.append(int(item))

k.sort()
print(k)
# [1, 2, 3, 4, 10, 22, 23, 200]


#11 楼

排序数字列表的简单方法

numlists = ["5","50","7","51","87","97","53"]
results = list(map(int, numlists))
results.sort(reverse=False)
print(results)


#12 楼

可能不是最好的python,但是对于像
['1','1.0','2.0','2','1.1','1.10','1.11','1.2',' 7','3','5'],预期目标
['1','1.0','1.1','1.2','1.10','1.11','2','2.0 ','3','5','7']帮助了我...
unsortedList = ['1','1.0','2.0','2', '1.1', '1.10', '1.11', '1.2','7','3','5']
sortedList = []
sortDict = {}
sortVal = []
#set zero correct (integer): examp: 1.000 will be 1 and breaks the order
zero = "000"
for i in sorted(unsortedList):
  x = i.split(".")
  if x[0] in sortDict:
    if len(x) > 1:
        sortVal.append(x[1])
    else:
        sortVal.append(zero)
    sortDict[x[0]] = sorted(sortVal, key = int)
  else:
    sortVal = []
    if len(x) > 1:
        sortVal.append(x[1])
    else:
        sortVal.append(zero)
    sortDict[x[0]] = sortVal
for key in sortDict:
  for val in sortDict[key]:
    if val == zero:
       sortedList.append(str(key))
    else:
       sortedList.append(str(key) + "." + str(val))
print(sortedList)


评论


欢迎来到SO!当您要回答一个已经被接受的旧问题(这个问题已经超过10年)(在这里就是这种情况)时,请问自己:我真的有很大的进步吗?如果没有,请考虑不要回答。

–提摩斯(Timus)
10月23日10:38

@timus,谢谢,发现了我的期望..

–user14505738
10月23日14:18

#13 楼

真正的问题是按字母数字排序。因此,如果您有一个列表
['1','2','10','19']并进行排序,则得到['1','10'。 '19','2']。即10排在2之前,因为它会看第一个字符并从该字符开始排序。
似乎python中的大多数方法都按该顺序返回东西。例如,如果您有一个名为abc的目录,且文件标记为1.jpg,2.jpg等,最多说15.jpg,并且您执行
file_list = os.listdir(abc),则file_list不会像您那样排序期望而是
file_list = ['1.jpg','11 .jpg'---'15.jpg','2.jpg]。如果处理文件的顺序很重要(大概是您用数字命名的原因),那么该顺序就不是您认为的那样。您可以使用“零”填充来避免这种情况。例如,如果您有一个列表
alist = ['01','03','05','10','02','04','06],然后对其进行排序,则得到订购您
。 alist = ['01','02'等],因为第一个字符是1之前的0。您所需的填充零数由列表中的最大值确定。例如,如果最大的填充数介于100和1000,您需要填充一位数字,例如001、002 --- 010,011--100、101等。

#14 楼

scores = ['91','89','87','86','85']
scores.sort()
print (scores)


这在python版本3中对我有用,尽管在版本2中没有。

评论


尝试在那里用'11和'100'进行排序,这就是事情变得有趣的时候。

–彭茨
17年1月5日在18:09