繁体   English   中英

Sorted(list, key=itemgetter) 未在 Python 中正确排序项目列表

[英]Sorted(list, key=itemgetter) not sorting a list of items properly in Python

list1 = ["1.11", "2.0.0", "1.2", "2", "0.1", "1.2.1", "1.1.1", "2.0"]

from operator import itemgetter

def solution(data):

    parse_list = []
    parse_list2 = []
    final_solution = []
    for x in data:
        y = x.split('.')
        if len(y) == 1:
            x = "{}.{}.{}".format(y[0], '-1', '-1')
            parse_list.append(x)
        if len(y) == 2:
            x = "{}.{}.{}".format(y[0], y[1], '-1')
            parse_list.append(x)
        if len(y) == 3:
            x = "{}.{}.{}".format(y[0], y[1], y[2])
            parse_list.append(x)
    print(parse_list)

    parse_list2 = sorted(parse_list, key=itemgetter(0, 1, 2))

    # print(parse_list)
    print(parse_list2)

    def unparse(x):

        y = x.split('.')
        if int(y[1]) < 0:
            x = '{}'.format(y[0])
            final_solution.append(x)
            return
        if int(y[2]) == -1:
            x = '{}.{}'.format(y[0], y[1],)
            final_solution.append(x)
            return
        if int(y[2]) >= 0:
            x = '{}.{}.{}'.format(y[0], y[1], y[2])
            final_solution.append(x)
            return
    for x in parse_list2:
        x = unparse(x)
    print(final_solution)

输出:

['1.11.-1', '2.0.0', '1.2.-1', '2.-1.-1', '0.1.-1', '1.2.1', '1.1.1', '2.0.-1']
['0.1.-1', '1.11.-1', '1.1.1', '1.2.-1', '1.2.1', '2.-1.-1', '2.0.0', '2.0.-1']
['0.1', '1.11', '1.1.1', '1.2', '1.2.1', '2', '2.0.0', '2.0']

我不理解为什么

parse_list2 = sorted(parse_list, key=itemgetter(0, 1, 2))

不将输出排序为

['1.11.-1', '2.0.0', '1.2.-1', '2.-1.-1', '0.1.-1', '1.2.1', '1.1.1', '2.0.-1']
['0.1.-1', '1.1.1', '1.2.-1', '1.2.1', '1.11.-1', '2.-1.-1', '2.0.0', '2.0.-1']
['0.1', '1.1.1', '1.2', '1.2.1', '1.11', '2', '2.0.0', '2.0']

因为 2 小于 11

请有人帮助我调整我的代码以使其正常工作(而不是给我一个不同但功能强大的代码)或向我解释为什么我的逻辑不起作用。

您的值未排序,因为它们比较的是字符串,而不是整数。

这是我对它们进行排序的方式:

def toIntList(x):
    intList = []
    for value in x.split("."):
        intList.append(int(value))
    return intList

list1 = ["1.11", "2.0.0", "1.2", "2", "0.1", "1.2.1", "1.1.1", "2.0"]

# Using a function
sort1 = sorted(list1, key=toIntList)

# Using a lambda-function:
sort2 = sorted(list1, key=lambda x: [int(i) for i in x.split(".")])

print(list1) # Output: ['1.11', '2.0.0', '1.2', '2', '0.1', '1.2.1', '1.1.1', '2.0']
print(sort1) # Output: ['0.1', '1.1.1', '1.2', '1.2.1', '1.11', '2', '2.0', '2.0.0']
print(sort2) # Output: ['0.1', '1.1.1', '1.2', '1.2.1', '1.11', '2', '2.0', '2.0.0']

一些技巧:

  • import总是在开头(我删除了它,因为我不再使用它了,但将它们始终放在文件的顶部,通常是三个导入块,首先是标准库,其次是第三方库,然后是导入到其他文件你的程序第三)
  • 一级函数和类声明之间的 2 个空行
  • 如果前一个为真, elif将不会尝试条件,因此我们避免了不必要的条件检查。
  • parse_list将存储三个整数的元组,例如(1, 11, -1)
  • parse_list = sorted(parse_list)等价于parse_list.sort()就地进行。
  • unparse函数将返回每个值,而不是附加到属于solution函数而不是unparse函数的final_solution列表。
def solution(data):
    parse_list = []
    for x in data:
        y = x.split('.')
        if len(y) == 1:
            parse_list.append((int(y[0]), -1, -1))
        elif len(y) == 2:
            parse_list.append((int(y[0]), int(y[1]), -1))
        elif len(y) == 3:
            parse_list.append((int(y[0]), int(y[1]), int(y[2])))
    print(parse_list)

    parse_list.sort()
    print(parse_list)

    def unparse(x):
        if x[1] < 0:
            return '{}'.format(x[0])
        if x[2] < 0:
            return '{}.{}'.format(x[0], x[1])
        return '{}.{}.{}'.format(x[0], x[1], x[2])

    final_solution = []
    for x in parse_list:
        final_solution.append(unparse(x))
    print(final_solution)


if __name__ == '__main__':
    list1 = ["1.11", "2.0.0", "1.2", "2", "0.1", "1.2.1", "1.1.1", "2.0"]
    solution(list1)

这也可以优化:

def solution(data):
    parse_list = sorted([tuple(map(int, item.split('.'))) for item in data])
    final_solution = ['.'.join(map(str, item)) for item in parse_list]
    print(final_solution)


if __name__ == '__main__':
    list1 = ["1.11", "2.0.0", "1.2", "2", "0.1", "1.2.1", "1.1.1", "2.0"]
    solution(list1)

让我们分解这个解决方案:

  1. [doSomethingWith(item) for item in data]创建一个列表,其中每个元素都是doSomethingWith(item) ,每次使用data的元素之一。
  2. doSomethingWith(item)在我们的例子中是tuple(map(int, item.split('.')))
    1. item是例如"1.11"
    2. item.split('.')给了我们一个字符串列表: ["1", "11"]
    3. map(f, iterable)将函数f应用于map(f, iterable)每个元素并返回一个类似列表的对象(它不完全是一个列表,而是类似的)。 在我们的例子中fint所以我们将子字符串转换为整数: [1, 11] <-- 不是真正的列表,但类似
    4. 我们使用外部tuple()将这个类似列表的对象转换为一个元tuple()(1, 11)
  3. 外部sorted()将对此列表进行排序,无需担心缺少(1, 0) < (1, 0, 0)这样的元素(1, 0) < (1, 0, 0)因此它们会正确排序。
  4. 所以parse_list是一个已经排序的整数元组列表: [(0, 1), (1, 1, 1), ...]
  5. 再次使用[doSomethingWith(item) for item in parse_list]语句,因此我们正在创建一个新列表,对parse_list每个元素执行某些parse_list
  6. doSomethingWith(item)在这种情况下是'.'.join(map(str, item))
    1. item是例如(1, 11)
    2. map(str, item)正在将我们拥有的item每个元素转换为字符串: ["1", "11"] <-- 不是真正的列表,但类似
    3. '.'.join()通过 '.' 连接字符串列表: "1.11"
  7. 所以final_result是所需的输出: ["0.1", "1.1.1", ...]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM