如何按数字顺序对字符串列表进行排序

2024-12-06 08:39:00
admin
原创
89
摘要:问题描述:我知道这听起来微不足道,但我没有意识到sort()Python 的功能很奇怪。我有一个“数字”列表,它们实际上是字符串形式,所以我首先将它们转换为 int,然后尝试排序。list1=["1","10","3","22",...

问题描述:

我知道这听起来微不足道,但我没有意识到sort()Python 的功能很奇怪。我有一个“数字”列表,它们实际上是字符串形式,所以我首先将它们转换为 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']

我查看了一些与对数字集进行排序相关的算法,但我发现所有算法都涉及对字母数字集进行排序。

我知道这可能是一个无需思考的问题,但是谷歌和我的教科书并没有提供比该.sort()功能更有用或更无用的东西。


解决方案 1:

您实际上并未将字符串转换为整数。或者说,您确实转换了,但并未对结果执行任何操作。您想要的是:

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

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

list1 = ["1","10","3","22","23","4","2","200"]
# call int(x) on each element before comparing it
list1.sort(key=int)
# or if you want to do it all in the same line
list1 = sorted([int(x) for x in list1]) 

解决方案 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

解决方案 3:

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

list1.sort(key=int)

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

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, ...]

解决方案 6:

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

for item in list1:
   item=int(item)

没有按照您想象的那样做 -item没有被放回到列表中,而是被简单地扔掉了。

key=int无论如何,正确的解决方案是按照其他人向您展示的方式使用。

解决方案 7:

Seamus Campbell 的答案在 Python 2.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', '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],然后您对其运行“sort”,您将获得所需的顺序,alist=['01', '02', etc.],因为第一个字符是 0,它位于 1 之前。您需要的零填充量由列表中的最大值决定。

例如,如果最大值在 100 到 1000 之间,则需要填充个位数,如 001、002 --- 010、011--100、101 等。

解决方案 10:

最新的解决方案是正确的。您正在将解决方案读取为字符串,在这种情况下,顺序为 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)

解决方案 11:

我来这里寻找一个通用字符串,其中包含任意位置的数字,我认为这在当前答案中并没有真正解决(或者,如果涵盖,则更简单)。

我想出了一个针对这种情况的简单解决方案:

def numeric_sort(input: Iterable[str]) -> List[str]:
    def repl(num):
        return f"{int(num[0]):010d}"

    return sorted(input, key=lambda i: re.sub(r'(d+)', repl, i))


def test_numeric_sort():
    assert numeric_sort(["a2", "a11",  "a1"])   == ["a1", "a2", "a11"]
    assert numeric_sort(["a2", "a11",  "b1"])   == ["a2", "a11", "b1"]
    assert numeric_sort(["a2", "a2b3", "a2b1"]) == ["a2", "a2b1", "a2b3"]

您需要为最大数量选择一个限制(应该不是问题)。调整正则表达式后,您可以int...:d更改。float...:f

解决方案 12:

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

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

解决方案 13:

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

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]

解决方案 14:

它可能不是最好的 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): example: 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)

解决方案 15:

转换为 int 很好,但您不能总是将整个字符串转换为 int。所以我只是将d+子字符串转换为 int。

import re
from typing import List

def make_string_sortable_numerically(string:str) -> List[str|int]:
    def isolate_digits(x:str) -> List[str]:
        return re.split(r'(d+)', x)
    def convert_digits_to_int(substrings:List[str]) -> List[str|int]:
        return [int(x) if str.isdigit(x) else x for x in substrings]
    return convert_digits_to_int(isolate_digits(string))

unsorted = ["abc100", "abc11"]
print(f"sored normally: {sorted(unsorted)}")
print(f"sorted numerically: {sorted(unsorted, key=make_string_sortable_numerically)}")
sored normally: ['abc100', 'abc11']
sorted numerically: ['abc11', 'abc100']

实际上,上述答案与https://stackoverflow.com/a/40039556/6307935存在同样的问题。我认为以下几点应该是可靠的:

def _make_string_sortable_numerically(string:str) -> List[Tuple[int, int]]:
    """
    each character becomes a tuple of two ints. The first int is either 0,1, or 2
    0 for characters that come before numbers, 1 for numbers, 2 for after numbers
    the second int is the unicode value of the character, or the integer value of the number
    that this character is a part of.
                $         7         8         9         a        ~
    "$789a~" -> [[0, 36], [1, 789], [1, 789], [1, 789], [2, 97], [2, 126]]
    """
    output = [[None, None] for _ in range(len(string))]
    skip_these_indexes = [False]*len(string)
    for i, char in enumerate(string):
        if skip_these_indexes[i]:
            continue
        char_int = ord(char)
        if char_int < ord("0"):
            output[i] = (0, char_int)
        elif str.isdigit(char):
            first_digit_index = i
            last_digit_index = i
            while (last_digit_index < len(string)-1 and str.isdigit(string[last_digit_index+1])):
                last_digit_index += 1
            this_number = int(string[first_digit_index:last_digit_index+1])
            for digit_index in range(first_digit_index, last_digit_index+1):
                skip_these_indexes[digit_index] = True
                output[digit_index] = (1, this_number)
        elif char_int > ord("9"):
            output[i] = (2, char_int)
    return output

解决方案 16:

使用:

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

在我使用 Python 版本 3 时,此方法有效,但在版本 2 中则无效。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1019  
  IPD(Integrated Product Development,集成产品开发)是一种以客户需求为核心、跨职能团队协作为基础的产品开发方法。它通过整合市场、研发、制造、供应链等各个环节的资源与信息,实现高效的产品开发流程。IPD不仅是一种方法论,更是一种系统化的管理思维,旨在缩短产品开发周期、降低开发成本、提高产品...
IPD培训课程   0  
  华为的IPD(集成产品开发)流程是全球范围内备受认可的产品开发管理体系,其核心在于通过跨部门协作和系统化的流程管理,提升产品开发效率和质量。在IPD流程中,团队建设与领导力培养是两个至关重要的环节。高效的团队能够确保项目顺利推进,而优秀的领导力则是团队凝聚力和执行力的保障。本文将从团队建设的重要性、领导力在IPD中的核...
IPD集成产品开发流程   0  
  华为的集成产品开发(IPD)流程是其成功的关键因素之一,它不仅提升了产品开发的效率,还通过系统化的风险管理机制确保了项目的顺利推进。在IPD流程中,风险管理被视为贯穿始终的核心环节,其目的是在项目初期识别潜在问题,并在整个开发周期中持续监控和应对风险。通过有效的风险管理,华为能够最大限度地减少项目延误、成本超支和质量问...
IPD结构化流程   0  
  在项目管理领域,CDCP(Critical Decision Control Point)评审是确保项目成功的关键环节之一。CDCP评审的核心在于通过系统化的决策流程,确保项目在每个关键节点都能做出正确的选择,从而降低风险、提高效率并最终实现项目目标。然而,许多项目团队在CDCP评审过程中常常面临决策效率低下、信息不对...
华为IPD流程   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用