【问题标题】:How to sort a list of strings numerically?如何对字符串列表进行数字排序?
【发布时间】:2011-03-26 11:05:59
【问题描述】:

我知道这听起来微不足道,但我没有意识到 Python 的 sort() 函数很奇怪。我有一个实际上是字符串形式的“数字”列表,所以我首先将它们转换为整数,然后尝试排序。

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。是什么让您认为 list 正在更新?
  • 当 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)

标签: python sorting


【解决方案1】:

您实际上还没有将字符串转换为整数。或者更确切地说,你做了,但是你没有对结果做任何事情。你想要的是:

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

如果由于某种原因您需要保留字符串而不是整数(通常是个坏主意,但也许您需要保留前导零或其他东西),您可以使用 key 函数。 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 时,我得到 None
  • 如果列表元素存储为“整数”,这有效,如果是浮点值,应如何处理?例如,list1 = [1, 1.10, 1.11, 1.1, 1.2]
  • @KI4JGT 排序方法修改列表并返回无。因此,不要使用list1 = list1.sort(key=int),而只需使用list1.sort(key=int),list1 已经被排序了。
  • @KI4JGT .sort() 是一个就地运算符,它返回None,它对列表进行排序,你可能想使用sorted()
【解决方案2】:

我昨天遇到了同样的问题,发现了一个名为 natsort 的模块,它可以解决您的问题。使用:

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.1.9', '1.1.10')] sort int() 没有的版本上为我工作。真棒又优雅!谢谢!
【解决方案3】:

您可以将一个函数传递给key 参数到the .sort method。这样,系统将按 key(x) 而不是 x 进行排序。

list1.sort(key=int)

顺便说一句,要将列表永久转换为整数,请使用the map function

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

或列表理解

list1 = [int(x) for x in list1]

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

    • 也适用于套装!
    【解决方案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() 创建一个新列表。
    【解决方案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】:

        试试这个,它会按降序对列表进行就地排序(在这种情况下不需要指定键):

        过程

        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)

          排序的整数:

          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() 参数必须是字符串或数字,而不是“元组”
          • 另外,你的 stringList 中的字符串应该有引号。
          • 这是一个非常糟糕的预测:“最新的解决方案是正确的”;)
          【解决方案10】:

          真正的问题是 sort 按字母数字排序。所以如果你有一个清单 ['1', '2', '10', '19'] 并运行 sort 你得到 ['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' etc] 因为第一个字符是 0,它在 1 之前。您需要的零填充量由列表中的最大值决定。例如,如果最大值介于 100 和1000 您需要将单个数字填充为 001、002 ---010,011--100、101 等。

          【讨论】:

            【解决方案11】:

            如果您想使用数字字符串,最好使用另一个列表,如我的代码所示,它会正常工作。

            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]
            

            【讨论】:

              【解决方案12】:

              对数字列表进行排序的简单方法

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

              【讨论】:

                【解决方案13】:

                可能不是最好的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 年了)时(这里就是这种情况),请问问自己:我真的有实质性的改进吗?如果没有,请考虑不要回答。
                【解决方案14】:
                scores = ['91','89','87','86','85']
                scores.sort()
                print (scores)
                

                这对我使用 python 版本 3 有效,但在版本 2 中没有。

                【讨论】:

                • 尝试用 '11 和 '100' 进行排序,这时候事情就会变得有趣。
                猜你喜欢
                • 1970-01-01
                • 2010-09-07
                • 1970-01-01
                • 2013-07-02
                • 1970-01-01
                • 2015-03-26
                相关资源
                最近更新 更多