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

时间:2020-09-16 05:20:16

标签: python list sorting

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

请有人可以帮助我调整我的代码以使其正常工作(而不是给我另外一个功能齐全的代码),或者向我解释为什么我的逻辑不起作用。

2 个答案:

答案 0 :(得分:1)

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

这是我将其排序的方式:

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']

答案 1 :(得分:0)

一些提示:

  • import始终放在开头(我删除了它是因为我不再使用它,但始终将它们放在文件顶部,通常是三个导入块,首先是标准库,然后是第三方库其次,然后导入到程序的其他文件中)
  • 一级函数和类声明之间有2条空行
  • elif如果前一个条件为true,则不会尝试该条件,因此我们避免了不必要的条件检查。
  • parse_list将存储三个整数的元组,例如(1, 11, -1)
  • parse_list = sorted(parse_list)等效于parse_list.sort()
  • unparse函数将返回每个值,而不是附加到属于final_solution函数而不是solution函数的unparse列表中。
  • li>
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. 在我们的例子中,
  3. doSomethingWith(item)tuple(map(int, item.split('.')))
    1. item例如"1.11"
    2. item.split('.')为我们提供了一个字符串列表:["1", "11"]
    3. map(f, iterable)将函数f应用到iterable的每个元素,并返回一个类似列表的对象(它不完全是一个列表,但类似)。在我们的情况下,fint,因此我们将子字符串转换为整数:[1, 11] <-并非真正的列表,而是相似的
    4. 我们使用外部tuple()(1, 11)
    5. 将此类似于列表的对象转换为元组
  4. 外部sorted()将对该列表进行排序,无需担心缺少(1, 0) < (1, 0, 0)这样的元素,因此它们将正确排序。
  5. 所以parse_list是一个已排序的整数元组列表:[(0, 1), (1, 1, 1), ...]
  6. 再次执行[doSomethingWith(item) for item in parse_list]语句,因此我们正在创建一个新列表,对parse_list中的每个元素都执行操作。
  7. doSomethingWith(item)在这种情况下为'.'.join(map(str, item))
    1. item例如(1, 11)
    2. map(str, item)正在将我们拥有的item的每个元素转换为字符串:["1", "11"] <-并不是一个列表,但类似
    3. '.'.join()通过'。'加入一个约束列表:"1.11"
  8. 因此final_result是所需的输出:["0.1", "1.1.1", ...]