Как отсортировать словарь с ключами в виде строки чисел в Python

У меня есть словарь:

a = {'100':12,'6':5,'88':3,'test':34, '67':7,'1':64 } 

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

 a = {'1':64,'6':5,'67':7,'88':3, '100':12,'test':34 } 

  • Python - нужно ли запускать новый проект непосредственно в Python 3.x?
  • Как закрыть программу с помощью python?
  • Оценка списка лямбда-функций python оценивает только последний элемент списка
  • Как создать интернационализированное приложение Google App Engine
  • Невозможно установить пакеты в Pycharm
  • Соединения / очереди с несколькими резьбовыми соединениями
  • pythonic способ создать 3d dict
  • время python + эквивалент timedelta
  • 5 Solutions collect form web for “Как отсортировать словарь с ключами в виде строки чисел в Python”

    Как отмечают все остальные, словари имеют свой собственный заказ, и вы не можете просто сортировать их, как и список.

    Единственное, что я хотел бы добавить, это то, что если вы просто хотите просмотреть элементы словаря в отсортированном порядке, это просто:

     for k in sorted(a): print k, a[k] # or whatever. 

    Если вы предпочитаете понимать список (за Alex):

     sortedlist = [(k, a[k]) for k in sorted(a)] 

    Я хотел бы указать, что использование Alex key=int не будет работать с вашим примером, потому что один из ваших ключей – 'test' . Если вы действительно хотите, чтобы числа, отсортированные перед нечисловыми числами, вам нужно передать в cmp функцию:

     def _compare_keys(x, y): try: x = int(x) except ValueError: xint = False else: xint = True try: y = int(y) except ValueError: if xint: return -1 return cmp(x.lower(), y.lower()) # or cmp(x, y) if you want case sensitivity. else: if xint: return cmp(x, y) return 1 for k in sorted(a, cmp=_compare_keys): print k, a[k] # or whatever. 

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

     # Won't work for integers with more than this many digits, or negative integers. MAX_DIGITS = 10 def _keyify(x): try: xi = int(x) except ValueError: return 'S{0}'.format(x) else: return 'I{0:0{1}}'.format(xi, MAX_DIGITS) for k in sorted(a, key=_keyify): print k, a[k] # or whatever. 

    Это будет намного быстрее, чем использование функции cmp .

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

     def get_key(key): try: return int(key) except ValueError: return key a = {'100':12,'6':5,'88':3,'test':34, '67':7,'1':64 } print sorted(a.items(), key=lambda t: get_key(t[0])) 

    Однако в Python 3.1 (и 2.7) модуль collections содержит collections.OrderedDict ТипOrderedDict, который можно использовать для достижения эффекта, который вы хотите, как показано ниже:

     def get_key(key): try: return int(key) except ValueError: return key a = {'100':12,'6':5,'88':3,'test':34, '67':7,'1':64 } b = collections.OrderedDict(sorted(a.items(), key=lambda t: get_key(t[0]))) print(b) 

    9 лет назад Я отправил рецепт, который начинается

    Словари нельзя сортировать – сопоставление не имеет порядка!

    и показывает, как получить отсортированные списки из ключей и значений dict.

    С сегодняшним Python и вашими явно выраженными значениями я предлагаю:

     import sys def asint(s): try: return int(s), '' except ValueError: return sys.maxint, s sortedlist = [(k, a[k]) for k in sorted(a, key=asint)] 

    key=asint – это то, что говорит sorted для обработки этих строковых ключей как целые числа для сортировки, так что, например, '2' сортируется между '1' и '12' , а не после них обоих – это то, что вам кажется нужным, поскольку так же как и все ключи без цифр, сортируются после всех всех цифр. Если вам также нужно иметь дело с целыми строками с целыми числами, которые выражают целые числа, большие, чем sys.maxint, это немного сложнее, но все же выполнимо:

     class Infinity(object): def __cmp__(self, other): return 0 if self is other else 1 infinite = Infinity() def asint(s): try: return int(s), '' except ValueError: return infinite, s 

    В общем, вы можете получить более быстрые ответы быстрее, если уточнить свои точные требования с самого начала ;-).

    Словари неупорядочены. Вы не можете сортировать, как вы показываете, потому что результат a – это dict, а dicts не имеют порядка.

    Если вы хотите, скажем, перечислить список ключей в отсортированном порядке, вы можете использовать код как

     >>> def my_key(dict_key): ... try: ... return int(dict_key) ... except ValueError: ... return dict_key ... >>> sorted(a, key=my_key) ['1', '6', '67', '88', '100', 'test'] 

    Это зависит от глупого поведения Python, что экземпляры str всегда больше, чем экземпляры int . (Поведение исправлено в Python 3.) В оптимальном дизайне ключи вашего диктата будут вещами, которые вы можете сравнить, и вы не будете смешивать строки, представляющие числа со строками, представляющими слова.

    Если вы хотите сохранить ключи в упорядоченном порядке, вы можете использовать модуль bisect или реализовать сопоставление, основанное на структуре данных дерева. Модуль bisect не принимает key аргумент, такой как сортировка, потому что это потенциально неэффективно; вы бы использовали шаблон decorate-use-undecorate, если вы решили использовать bisect , сохраняя отсортированный список, который зависит от результата ключевой функции.

    Если вы устанавливаете мой пакет blist , он включает тип sorteddict . Тогда вы могли бы просто:

     from blist import sorteddict def my_key(dict_key): try: return int(dict_key) except ValueError: return dict_key a = {'100':12,'6':5,'88':3,'test':34, '67':7,'1':64 } print sorteddict(my_key, **a).keys() 

    Вывод:

     ['1', '6', '67', '88', '100', 'test'] 
    Python - лучший язык программирования в мире.