Комплексная сортировка - Multi Key

Я использую Python 2.6.2. У меня есть словарь, graph , который имеет кортеж (источник, место назначения) в качестве ключа с определенным весом в качестве его значения.

Хотелось бы отсортировать graph на основе источника в порядке убывания веса. В кортеже графа с другим местом назначения может быть более одного источника.

graph= {(2, 18): 0, (5, 13): 2, (0, 10): 2, (0, 36): 1, (3, 14): 2, (5, 23): 2, (0, 24): 1, (4, 32): 7, (2, 29): 0, (3, 27): 2, (0, 33): 2, (5, 42): 2, (5, 11): 2, (5, 39): 3, (3, 9): 8, (0, 41): 4, (5, 16): 5, (4, 17): 7, (4, 44): 7, (0, 31): 2, (5, 35): 5, (4, 30): 7}

Создал промежуточный словарь, source_dict , у которого есть источник как ключ и накопленный вес, основанный на источнике как его значение, {source: weight}

source_dict={0: 12, 2: 0, 3: 12, 4: 28, 5: 21}

После выполнения функции сортировки, как показано ниже,

source_desc_sort=sorted(source_dict.items(), key=lambda x: x[1], reverse=True)
sortkeys = dict((x[0], index) for index,x in enumerate(source_desc_sort))
graph_sort = sorted(graph.iteritems(), key=lambda x: sortkeys[x[0][0]])

Я получаю отсортированный граф graph_sort , как показано ниже,

graph_sort= [((4, 17), 7), ((4, 44), 7), ((4, 30), 7), ((4, 32), 7), ((5, 23), 2), ((5, 35), 5), ((5, 13), 2), ((5, 42), 2), ((5, 11), 2), ((5, 39), 3), ((5, 16), 5), ((0, 10), 2), ((0, 36), 1), ((0, 24), 1), ((0, 33), 2), ((0, 41), 4), ((0, 31), 2), ((3, 14), 2), ((3, 27), 2), ((3, 9), 8), ((2, 29), 0), ((2, 18), 0)]

Если вы отметите в graph_sort , порядок ключей для того же источника не важен, например, для кортежей с 5 в качестве источника, ((5, 23), 2) может быть раньше ((5, 35), 5) или после того, как одно из них имеет более низкое значение, чем другое.

Теперь это мои проблемы, которые я пытаюсь решить с 2 дня назад,

Пересмотрено source_dict на source_dict_angle с углом в качестве дополнительной информации, {source: {angle: weight}}

source_dict_angle={0: {0: 2, 90: 4, 180: 6}, 2: {0: 0, 270: 0}, 3: {180: 4, 270: 8}, 4: {0: 7, 180: 21}, 5: {0: 6, 90: 10, 180: 2, 270: 3}}

Мне нравится сортировать то же, что и выше, но на основе угла источника. Например, кортежи с 4 в качестве источника и с адресатом (-ами) в угле 180 должны начинаться сначала, так как он имеет наибольшее значение i.e 21. Затем следуют кортежи с 5 в качестве источника и с местом назначения (-ами) в угле 90 и так далее.

Имеет посреднический словарь, relation_graph , который имеет информацию о местоположении назначения относительно источника, {источник: {angle: destination: value}}

relation_graph={0: {0: {32: [1], 36: [1], 23: [1], 24: [1], 16: [1]}, 90: {3: [1], 41: [1], 44: [1]}, 180: {33: [1], 10: [1], 31: [1]}}, 1: {}, 2: {0: {18: [1]}, 270: {29: [1]}}, 3: {180: {27: [1], 14: [1], 31: [1]}, 270: {0: [1], 33: [1], 36: [1], 9: [1], 1: [1], 24: [1], 41: [1], 10: [1]}}, 4: {0: {32: [1], 18: [1], 23: [1]}, 180: {0: [1], 33: [1], 44: [1], 14: [1], 15: [1], 17: [1], 21: [1], 41: [1], 27: [1], 30: [1], 31: [1]}}, 5: {0: {42: [1], 11: [1], 23: [1]}, 90: {7: [1], 8: [1], 16: [1], 35: [1]}, 180: {0: [1], 13: [1], 14: [1], 44: [1]}, 270: {1: [1], 2: [1], 39: [1], 29: [1]}}} 

Ожидаемый результат

graph_sort_angle= [((4, 17), 7), ((4, 44), 7), ((4, 30), 7), ((5, 35), 5), ((5, 16), 5), ((3, 9), 8), ...

Я пока не могу найти решение для этого, я пытаюсь повторно использовать решение, которое я сделал для graph_sort , но он не работает. Чувствую, что должен делать это по-другому.

Есть ли способ использовать тот же подход, что и для graph_sort ?

Цените, если вы можете дать мне несколько указателей.

Будет продолжаться до этого.

Additional Explanation 09 Jan 2013 9.30PM : Lennart Regebro

Я хотел бы отсортировать ключи graph (tuple) на основе нисходящих значений из source_dict_angle .

graph is composed of (source, destination) but source_dict_angle only have source and angle information, {source:{angle:weight}}. It does not have destination information. We would not be able to sort the tuples from graph as we did in the first example.

Мы даем (не вычисляем) relation_graph , где у нас есть информация источника, угла и адресата, {источник: {angle: destination: value}}. Мы будем использовать этот словарь, чтобы узнать, какие пары источников, с которыми назначается какой-то угол (0 град., 90 градусов, 180 градусов или 270 градусов).

Итак, мы

  1. Сначала обратитесь к source_dict_angle , чтобы узнать, какое значение является самым высоким. В данном примере источник 4 с углом 180 градусов имеет самое высокое значение i.e 21

  2. Мы сравниваем все назначения источника 4 с углом 180 от relation_graph , то есть [0, 33, 44, 14, 15, 17, 21, 41, 27, 30, 31] если он существует в графе . Если да, мы оцениваем кортеж (Source, Destination) в первой позиции, т. Е. (4, 17). Это также можно сделать по-другому, поскольку нам нужно сортировать Source 4, мы проверяем, существует ли какой-либо пункт назначения Source 4 в graph , в углу 180 источника 4 в relation_graph . Если да, мы ранжируем (Source, Destination) кортеж в первой позиции. Поскольку один и тот же источник может быть сопряжен с несколькими адресами, использующими один и тот же угол, мы можем иметь более одного (Source, Destination) кортежей. например, (4, 17), (4, 44) и (4, 30). Это означает, что источник 4 использует угол 180 для соединения с Destination 17, Destination 44 и Destination 30, следовательно, 3 пары кортежей. Порядок между этими тремя парами не является проблемой.

  3. Как только это будет сделано, мы перейдем к следующему наивысшему значению в source_dict_angle , выполнив вышеуказанные шаги, пока все источники не будут отсортированы в порядке убывания.

0
nl ja de
Знаете ли вы, что ключ не должен возвращать скаляр, но может возвращать сопоставимые объекты? Например, в вашем случае было бы целесообразно возвращать кортежи с самым важным атрибутом (источником) в качестве первого элемента, менее важным (весом) как вторым и так далее.
добавлено автор patrys, источник
@patrys Я этого не знал. Объяснение в docs.python.org/2/library/functions.html#sorted кажется кратким. Я googling, чтобы узнать больше о том, что вы указали. Я вижу на примере Lennart Regebro ниже, он показал ключ, вызывающий функцию. Это для меня ново, читайте больше и просматривайте примеры сейчас. благодаря
добавлено автор Saravanan K, источник

1 ответы

Пропустите промежуточный словарь, это не обязательно.

Для сортировки по источнику вы просто выполните:

graph_sort = sorted(graph.iteritems(), key=lambda x: x[0][0])

Для сортировки по углу вы делаете:

def angle(x):
   key, value = x
   source, destination = key
   return 

graph_sort = sorted(graph.iteritems(), key=angle)

Обновить:

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

Из того, что я могу собрать из вашего вопроса, у вас есть словарь элементов графика, который сохраняет источник, назначение и вес. Затем у вас есть еще один словарь, который сохраняет свет, снова. Затем у вас есть третий словарь, который удерживает угол.

Вместо этого просто выполните это:

class Graph(object):
    def __init__(self, source, destination, weight, angle):
        self.source = source
        self.destination = destination
        self.weight = weight
        self.angle = angle

Ваша проблема сортировки теперь тривиальна.

2
добавлено
@SaravananK: вам нужно прекратить использовать множество разных словарей, чтобы хранить разные данные, которые все принадлежат друг другу. Создайте класс для элемента, который хранит всю информацию. Я обновил ответ.
добавлено автор Lennart Regebro, источник
@LennartRegebro, Graph выглядит как кандидат, чтобы стать collections.namedtuple .
добавлено автор patrys, источник
Извините, если я не понял. Я начинаю и занимаюсь когда-то, чтобы читать и понимать ваше кодирование. Я сортирую, основываясь на значении source_dict, а не на ключевом источнике. Промежуточный словарь не рассчитан, а используется для решения этой проблемы. Я обновил свое письмо выше, чтобы лучше объяснить. Сообщите, могу ли я вас неправильно понять
добавлено автор Saravanan K, источник
Python
Python
7 654 участник(ов)

Уютный чат для профессионалов, занимающихся поиском питоньих мудростей. Как не получить бан: https://t.me/ru_python/577926

Python beginners
Python beginners
4 449 участник(ов)

Вопросы про Python для чайников. Cпам и троллинг неприемлем. Не злоупотребляйте стикерами. Частозадаваемые вопросы: https://github.com/ru-python-beginners/faq/blob/master/README.md Статистика тут: https://grstats.me/chat/x4qym2k5uvfkr3al6at7

pro.python
pro.python
1 090 участник(ов)

Сообщество разработчиков под Python Создатель: @rodgelius

Rude Python
Rude Python
971 участник(ов)

Python без „девочек”, здесь матерятся и унижают Django. Not gay friendly. Правила: t.me/rudepython/114107 @rudepython | t.me/rudepython

rupython
rupython
509 участник(ов)

Группа создана с целью оперативного получения ответов на возникающие вопросы по разработке на яп python, смежные темы, а также человеческого общения. Приветствую!

Python-programming
Python-programming
266 участник(ов)

Чат группы вконтакте https://vk.com/python_community