Сложная сортировка списка диктов по ключу: возрастание и убывание для каждого набора значений ключа - PullRequest
2 голосов
/ 22 марта 2019

У меня есть список диктов, которые я хочу отсортировать по его ключам сегмента, которые являются списками кортежей:

example = [{'segment': [(329, 363), (379, 397)], 'name': '1'},
           {'segment': [(329, 336), (339, 341), (396, 399)], 'name': '2'},
           {'segment': [(329, 363), (379, 399)], 'name': '3'},
           {'segment': [(329, 336), (337, 357), (396, 399)], 'name': '4'}]

Сортированный список должен выглядеть следующим образом:

sorted_example = [{'segment': [(329, 363), (379, 399)], 'name': '3'},
                  {'segment': [(329, 336), (337, 357), (396, 399)], 'name': '4'},
                  {'segment': [(329, 336), (339, 341), (396, 399)], 'name': '2'},
                  {'segment': [(329, 363), (379, 397)], 'name': '1'}]

Мой желаемый вывод отсортирован таким образом, что я могу легко проверить, полностью ли содержится dict [n + 1] в dict [n].

Итак, сначала я хочу отсортировать по возрастанию по первому элементу первого кортежа, а затем по второму элементу последнего кортежа по убыванию.
Это нормально для случаев, подобных dict 1 и 3, но для других dictкак 2 и 4, я должен перебрать все кортежи и отсортировать по возрастанию по первому элементу и по убыванию по второму.

Мой код для выполнения первого шага:

sorted_example = sorted(example, key=lambda k: (k['segment'][0][0], -k['segment'][-1][1]))

Но я не могу понять, как перебирать все кортежи в одном списке и сортировать их по возрастанию и убыванию, как описано выше.

Я был бы очень, очень рад, если бы кто-нибудь дал мне подсказку!

1 Ответ

1 голос
/ 22 марта 2019

Вы можете использовать генераторное выражение, которое перебирает кортежи данного подсписка в dict и возвращает кортеж элементов со вторым элементом, который отменяется, так что он сортируется в порядке убывания. Распакуйте выражение генератора в выходной кортеж ключевой функции, чтобы оно учитывалось после элементов, помещенных в ваше первое правило:

sorted(example, key=lambda k: (k['segment'][0][0], -k['segment'][-1][1], *((a, -b) for a, b in k['segment'])))

Возвращает:

[{'segment': [(329, 363), (379, 399)], 'name': '3'},
 {'segment': [(329, 336), (337, 357), (396, 399)], 'name': '4'},
 {'segment': [(329, 336), (339, 341), (396, 399)], 'name': '2'},
 {'segment': [(329, 363), (379, 397)], 'name': '1'}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...