Как отсортировать список с интервалами, но в строковом формате - PullRequest
0 голосов
/ 07 августа 2020

У меня есть список строк, которые изначально были интервалом, и мне пришлось преобразовать их в строку. Теперь я хочу отсортировать список на основе первого числа в кортеже.

Список ввода:

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

Ответы [ 2 ]

3 голосов
/ 07 августа 2020

Вы можете использовать ast.literal_eval в качестве ключа для сортировки

>>> import ast
>>> in_lst = ['(-100, 20)', '(100, 200)', '(20, 100)']
>>> 
>>> sorted(in_lst, key=ast.literal_eval)
['(-100, 20)', '(20, 100)', '(100, 200)']
2 голосов
/ 07 августа 2020

Если вам нужно работать с интервалами как с включающими, так и с исключительными границами, вы можете использовать Часть и ее 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 в качестве ключа сравнения для функции sorted :

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

или даже sort список на месте:

in_lst.sort(key=ast.literal_eval)
print(in_lst)
# ['(-100, 20)', '(20, 100)', '(100, 200)']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...