首页 > 解决方案 > 如何对包含间隔但以字符串格式的列表进行排序

问题描述

我有一个字符串列表,它们最初是间隔的,我必须将它们转换为字符串。现在我想根据元组中的第一个数字对列表进行排序。

输入列表:

in_lst = ['(-100, 20)', '(100, 200)', '(20, 100)']

当我使用以下代码时:

sorted(in_lst)

它返回以下内容:

['(-100, 20)', '(100, 200)', '(20, 100)']

虽然预期的输出是

['(-100, 20)', '(20, 100)', '(100, 200)']

此外,我将能够处理以下包容性边界:

['(-100, 20]', '(100, 200]', '(20, 100]']

标签: pythonsorting

解决方案


如果您需要使用包含和排除边界的 inteval,您可以使用part及其from_string函数:

import portion
portion.from_string('(-100, 20]', conv=int)
# (-100,20]

此函数提供了处理间隔的结构,并且可以比较这些结构:

interval_1 = portion.from_string('(-100, 20]', conv=int)
interval_2 = portion.from_string('(100, 200]', conv=int)

print(interval_1 <= interval_2)  # True
print(interval_1 >= interval_2)  # False

因此,通过将字符串转换为区间结构,您可以对它们进行排序。为方便起见,您可能需要一个函数来处理此转换,您将能够将其传递给排序函数:

l = ['(-100, 20]', '(100, 200]', '(20, 100]']

def string_to_interval(conv):
    def key_func(string):
        return portion.from_string(string, conv=conv)
    return key_func

print(sorted(l, key=string_to_interval(int)))
# ['(-100, 20]', '(20, 100]', '(100, 200]']

如果您的间隔边界是浮动的,则可以sorted(l, key=string_to_interval(float))改用


如果您只需要使用独占边界,则可以使用ast.literal_eval将字符串安全地转换为元组:

import ast


in_lst = ['(-100, 20)', '(100, 200)', '(20, 100)']

tuples = map(ast.literal_eval, in_lst)

然后你只需要对你的元组列表进行排序:

print(sorted(tuples))
# [(-100, 20), (20, 100), (100, 200)]

如果你想保留你的字符串,你还可以提供排序函数ast.literal_eval的比较键:

print(sorted(in_lst, key=ast.literal_eval))
# ['(-100, 20)', '(20, 100)', '(100, 200)']

甚至对列表进行适当的排序:

in_lst.sort(key=ast.literal_eval)
print(in_lst)
# ['(-100, 20)', '(20, 100)', '(100, 200)']

推荐阅读