Сортировка словарных ключей по значениям в списке? - PullRequest
3 голосов
/ 13 февраля 2010

У меня есть словарь и список. Значения клавиш совпадают со значениями в списке, я просто пытаюсь выяснить, как отсортировать значения в словаре по значениям в списке.

>>> l = [1, 2, 37, 32, 4, 3]
>>> d = {
    32: 'Megumi', 
    1: 'Ai',
    2: 'Risa',
    3: 'Eri', 
    4: 'Sayumi', 
    37: 'Mai'
}

Я пытался использовать что-то вроде ...

>>> sorted(dict.keys(), key=list.index)

... но очевидно, что ключи возвращаются только в нужном порядке.

(Должен был понять в 3 часа ночи, что list и dict были ужасными именами, я изменил их на l и d соответственно.)

Ответы [ 5 ]

6 голосов
/ 13 февраля 2010

Не следите за встроенными dict и list

>>> L = [1, 2, 37, 32, 4, 3]
>>> D = {
...     32: 'Megumi',
...     1: 'Ai',
...     2: 'Risa',
...     3: 'Eri',
...     4: 'Sayumi',
...     37: 'Mai'
... }

# Seems roundabout to use sorted here
# This causes an index error for keys in D that are not listed in L
>>> sorted(D.items(), key=lambda x:L.index(x[0]))
[(1, 'Ai'), (2, 'Risa'), (37, 'Mai'), (32, 'Megumi'), (4, 'Sayumi'), (3, 'Eri')]
>>>

# I think this is more direct than using sorted.
# This also ignores/skips keys in D that aren't listed in L
>>> [(i,D[i]) for i in L]
[(1, 'Ai'), (2, 'Risa'), (37, 'Mai'), (32, 'Megumi'), (4, 'Sayumi'), (3, 'Eri')]
>>>
4 голосов
/ 13 февраля 2010

Вам не следует называть переменные dict и list, потому что тогда вы больше не сможете использовать встроенные методы. Я переименовал их в этом примере.

>>> l = [1, 2, 37, 32, 4]
>>> d = dict = {
...     32: 'Megumi', 
...     1: 'Ai',
...     2: 'Risa',
...     3: 'Eri', 
...     4: 'Sayumi', 
...     37: 'Mai'
... }

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

Но вы можете создать новый список, содержащий (ключ, значение) -туплицы из словаря, который отсортирован по первому списку:

>>> s = list((i, d.get(i)) for i in L)
>>> print s
[(1, 'Ai'), (2, 'Risa'), (37, 'Mai'), (32, 'Megumi'), (4, 'Sayumi')]

Или, если вас интересуют только значения:

>>> s = list(d.get(i) for i in L)
>>> print s
['Ai', 'Risa', 'Mai', 'Megumi', 'Sayumi']

Надеюсь, это поможет!

1 голос
/ 13 февраля 2010

Вы не можете отсортировать словарь, потому что словарь не упорядочен.

Вместо этого вы можете:

  • Получить все пары ключ-значение из словаря, отсортировать их и поместить в список или
  • Что вы уже делаете: сохраняйте отсортированный список ключей и используйте словарь, когда вам нужно значение, соответствующее ключу.
0 голосов
/ 13 февраля 2010

В Python 3.1 вы можете использовать класс OrderedDict :

from collections import OrderedDict

l = [1, 2, 37, 32, 4]
d = {
    32: 'Megumi', 
    1: 'Ai',
    2: 'Risa',
    3: 'Eri', 
    4: 'Sayumi', 
    37: 'Mai'
}

def myindex(element):
    try:
        return l.index(element)
    except ValueError:
        return -1 # nonexisting keys are appended to the beginning of the list

od = OrderedDict(sorted(d.items(), key = lambda t: myindex(t[0])))

print(od)

Поскольку я не знал, что вы хотите сделать с ключами, которых нет в списке, я просто возвращаю -1 в этом случае, что означает, что эти элементы каким-то образом добавляются в список (т.е. в нестабильном порядке) .

Мой пример напечатает

OrderedDict([(3, 'Eri'), (1, 'Ai'), (2, 'Risa'), (37, 'Mai'), (32, 'Megumi'), (4, 'Sayumi')])
0 голосов
/ 13 февраля 2010

Сортированный dict фактически является списком из двух кортежей, потому что в Python 2.x нет встроенных упорядоченных словарей. Вы почти получили решение, просто добавьте поиск значений после сортировки ключей:

[(k,dict[k]) for k in sorted(dict.keys(), key=list.index)]

Но происходит сбой, когда ключ отсутствует в list. Давайте добавим модификацию, чтобы поместить все такие значения в конец сортировки, упорядоченной по значению:

def _index(x): # Allow non-full key list to be used in sorting
    try: return (list.index(x), x)
    except ValueError: return (sys.maxint, x)

[(k,dict[k]) for k in sorted(dict.keys(), key=_index)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...