Обмен предметов в словаре и порядке - PullRequest
1 голос
/ 04 декабря 2011

Я пытаюсь взять словарь ключей и значений, а затем поменять местами соответствующие ключи и значения, просматривая ранее опубликованные вопросы. Я знаю, что вы можете менять ключи / значения словаря, используя что-то вроде:

newdict = dict((b,a) for a,b in D.items())

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

Итак, мой вопрос: есть ли способ поменять местами первую пару элементов, затем добавить их в список (чтобы они были в порядке), а затем добавить в новый словарь? Затем повторите этот процесс для второй пары терминов и так далее? Это может показаться глупым вопросом, но я его не понимаю, и любая помощь будет высоко оценена, как всегда. :)

Для пояснения вот что делает мой текущий код:

D = {1:2, 3:4, 5:6, 8:9, 20:11} #this is the input

{9: 8, 2: 1, 11: 20, 4: 3, 6: 5} #this is the output

В идеале я хотел бы, чтобы результат был:

{2:1, 4:3, 6:5, 9:8, 11:20}

Для справки мой код просто:

def invert():
    newdict = list((b,a) for a,b in D.items())

D = {1:2, 3:4, 5:6, 8:9, 20:11}

invert()

Ответы [ 5 ]

3 голосов
/ 04 декабря 2011

OrderedDict как часть решения

Как вы упомянули, dict не имеет какого-либо определенного порядка, поэтому вам нужно будет реализовать dict -подобную структуру данных, которую можно упорядочить.

Хорошим решением здесь является OrderedDict.Вы можете создать отсортированный OrderedDict так:

>>> D = {9: 8, 2: 1, 11: 20, 4: 3, 6: 5}
>>> import collections
>>> E = collections.OrderedDict((i, D[i]) for i in sorted(D))
>>> E
OrderedDict([(2, 1), (4, 3), (6, 5), (9, 8), (11, 20)])

Инвертирование словаря с использованием OrderedDict

Все ваше решение может выглядеть так:

>>> D = {9: 8, 2: 1, 11: 20, 4: 3, 6: 5}
>>> def invert(D):
    import collections
    return collections.OrderedDict((D[i], i) for i in sorted(D))

>>> invert(D)
OrderedDict([(1, 2), (3, 4), (5, 6), (8, 9), (20, 11)])

Делает ли этоработать для вас?

Поддержка в Python старше 2.7

OrderedDict доступна в строке Python 2.x начиная с версии 2.7 и в строке Python 3.x начиная с 3.1, но может бытьреализовано легко в старых версиях.Если вам это нужно в более старых версиях, см. этот вопрос (" OrderedDict для более старых версий Python ") и ответы .

1 голос
/ 04 декабря 2011

Вы действительно хотите использовать OrderedDicts для достижения этой цели. Порядок ввода вашего словаря не имеет отношения к тому, как он хранится внутри.

0 голосов
/ 04 декабря 2011

То, что вы пытаетесь сделать, невозможно, так как карта не организована:

В идеале я хотел бы, чтобы результат был: {2: 1, 4: 3, 6: 5, 9: 8, 11:20}

например, если вы создадите карту с {2: 1, 4: 3, 6: 5, 9: 8, 11:20} и распечатаете ее, вы увидитеэтот порядок будет потерян.

>>> {2:1, 4:3, 6:5, 9:8, 11:20}
{9: 8, 2: 1, 11: 20, 4: 3, 6: 5}  
>>> 
0 голосов
/ 04 декабря 2011

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

def invert():
    order = [b for a,b in D.items()]
    newdict = dict((b,a) for a,b in D.items())
    return order

D = {1:2, 3:4, 5:6, 8:9, 20:11}

order = invert()

#This will print out the values in the order you want:
for i in order:
    print(newdict[i])

При этом я даже не уверен, что (b,a) for a,b in D.items() возвращает элементыв текущем порядке словаря.Так что даже в функции invert вместо:

newdict = dict((b,a) for a,b in D.items())

вы можете написать:

#Think the initial order is saved in initial_order
newdict = dict((D[a],a) for a in initial_order)

Другой способ - использовать структуру списка, содержащую (index, значение) пары.Я хотел объяснить это, но @Joe уже сделал.

0 голосов
/ 04 декабря 2011

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

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

D = [(1,2), (3,4), (5,6), (8,9), (20,11)]

, чтобы инвертировать ее:

Di = [(x,y) for (y,x) in D]

и получить словарь, в котором вы можете искать вещи:

DictD = dict(D)
DictDi = dict(Di)
...