Как отсортировать словарь по значению?

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

Я могу сортировать по ключам, но как я могу сортировать на основе значений?

Примечание. Я прочитал вопрос о переполнении стека. Как отсортировать список словарей по значениям словаря в Python? и, возможно, я могу изменить свой код, чтобы иметь список словарей, но поскольку мне действительно не нужен список словарей, я хотел бы знать, есть ли более простое решение.

вопрос задан 5.03.2009
Gern Blanston
18345 репутация

41 ответов


  • 3633 рейтинг

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

    Например,

     import operator
    x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
    sorted_x = sorted(x.items(), key=operator.itemgetter(1))
     

    sorted_x будет список кортежей, отсортированных по второму элементу в каждом кортеже. dict(sorted_x) == x .

    И для тех, кто хочет сортировать ключи вместо значений:

     import operator
    x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
    sorted_x = sorted(x.items(), key=operator.itemgetter(0))
     

    В Python3, поскольку распаковка не разрешена [1], мы можем использовать

     x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
    sorted_by_value = sorted(x.items(), key=lambda kv: kv[1])
     
    ответ дан Devin Jeanpierre, с репутацией 56093, 5.03.2009
  • 989 рейтинг

    Проще всего: sorted(dict1, key=dict1.get)

    Ну, на самом деле можно сделать «сортировку по значениям словаря». Недавно мне пришлось сделать это в Code Golf (Stack Overflow question Code golf: Частотная диаграмма слов ). Сокращенный, проблема была такой: учитывая текст, подсчитывайте, как часто встречается каждое слово, и отображает список верхних слов, отсортированных по уменьшению частоты.

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

     from collections import defaultdict
    d = defaultdict(int)
    for w in text.split():
      d[w] += 1
     

    то вы можете получить список слов, упорядоченных по частоте использования с sorted(d, key=d.get) - сортировка итераций по клавишам словаря, используя количество вхождений слов в качестве ключа сортировки.

     for w in sorted(d, key=d.get, reverse=True):
      print w, d[w]
     

    Я пишу это подробное объяснение, чтобы проиллюстрировать, что люди часто подразумевают под «Я могу легко сортировать словарь по ключевым словам, но как я сортирую по значению» - и я думаю, что ОП пытался решить такую ​​проблему. И решение состоит в том, чтобы сделать список ключей, основанный на значениях, как показано выше.

    ответ дан Nas Banov, с репутацией 19037, 5.07.2010
  • 617 рейтинг

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

    sorted(d.items(), key=lambda x: x[1])

    Это сортирует словарь по значениям каждой записи в словаре от наименьшего до самого большого.

    ответ дан Mark, с репутацией 6195, 13.02.2010
  • 171 рейтинг

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

    Сортированный список значений dict:

     sorted(d.values())
     

    Список пар (ключ, значение), отсортированный по значению:

     from operator import itemgetter
    sorted(d.items(), key=itemgetter(1))
     
    ответ дан Roberto Bonvallet, с репутацией 20116, 5.03.2009
  • 131 рейтинг

    В последнем Python 2.7 у нас есть новый тип OrderedDict , который запоминает порядок, в котором элементы были добавлены.

     >>> d = {"third": 3, "first": 1, "fourth": 4, "second": 2}
    
    >>> for k, v in d.items():
    ...     print "%s: %s" % (k, v)
    ...
    second: 2
    fourth: 4
    third: 3
    first: 1
    
    >>> d
    {'second': 2, 'fourth': 4, 'third': 3, 'first': 1}
     

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

     >>> from collections import OrderedDict
    >>> d_sorted_by_value = OrderedDict(sorted(d.items(), key=lambda x: x[1]))
     

    OrderedDict ведет себя как обычный dict:

     >>> for k, v in d_sorted_by_value.items():
    ...     print "%s: %s" % (k, v)
    ...
    first: 1
    second: 2
    third: 3
    fourth: 4
    
    >>> d_sorted_by_value
    OrderedDict([('first': 1), ('second': 2), ('third': 3), ('fourth': 4)])
     
    ответ дан mykhal, с репутацией 11706, 5.07.2010
  • 77 рейтинг

    ОБНОВЛЕНИЕ: 5 ДЕКАБРЯ 2015 г. с использованием Python 3.5

    Хотя я нашел приемлемый ответ полезным, я также был удивлен тем, что он не был обновлен, чтобы ссылаться на OrderedDict из стандартного модуля коллекций библиотек как жизнеспособную, современную альтернативу, предназначенную для решения именно такого рода проблем.

     from operator import itemgetter
    from collections import OrderedDict
    
    x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
    sorted_x = OrderedDict(sorted(x.items(), key=itemgetter(1)))
    # OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])
     

    Официальная документация OrderedDict также предлагает очень похожий пример, но с использованием лямбда для функции сортировки:

     # regular unsorted dictionary
    d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
    
    # dictionary sorted by value
    OrderedDict(sorted(d.items(), key=lambda t: t[1]))
    # OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
     
    ответ дан arcseldon, с репутацией 18654, 5.12.2015
  • 66 рейтинг

    Часто бывает очень удобно использовать namedtuple . Например, у вас есть словарь «имя» в качестве ключей и «оценка» в качестве значений, и вы хотите сортировать по «оценке»:

     import collections
    Player = collections.namedtuple('Player', 'score name')
    d = {'John':5, 'Alex':10, 'Richard': 7}
     

    сначала сортировка с минимальным счетом:

     worst = sorted(Player(v,k) for (k,v) in d.items())
     

    сначала сортировка с наивысшим балл:

     best = sorted([Player(v,k) for (k,v) in d.items()], reverse=True)
     

    Теперь вы можете получить имя и оценку, скажем, второго лучшего игрока (index = 1) очень Pythonically следующим образом:

     player = best[1]
    player.name
        'Richard'
    player.score
        7
     
    ответ дан Remi, с репутацией 12411, 30.08.2011
  • 59 рейтинг

    В значительной степени то же, что и ответ Хэнка Гей;

    
        sorted ([(значение, ключ) для (ключ, значение) в mydict.items ()])
    
    

    Или немного оптимизирован, как предложил Джон Фухи;

    
        sort ((значение, ключ) для (ключ, значение) в mydict.items ())
    
    
    ответ дан user26294, с репутацией 3226, 5.03.2009
  • 53 рейтинг

    Начиная с версии Python 3.6 будет установлен встроенный диктофон

    Хорошие новости, поэтому исходный пример использования OP для пар отображения, полученных из базы данных с уникальными идентификаторами строк в виде ключей и числовых значений в виде значений во встроенный Python v3.6 + dict, должен теперь уважать порядок вставки.

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

     SELECT a_key, a_value FROM a_table ORDER BY a_value;
     

    будет храниться в двух кортежах Python, k_seq и v_seq (выровненных по числовому индексу и с той же длиной курса), затем:

     k_seq = ('foo', 'bar', 'baz')
    v_seq = (0, 1, 42)
    ordered_map = dict(zip(k_seq, v_seq))
     

    Разрешить вывод позже:

     for k, v in ordered_map.items():
        print(k, v)
     

    уступая в этом случае (для нового Python 3.6+ встроенного dict!):

     foo 0
    bar 1
    baz 42
     

    в том же порядке на значение v.

    Где в Python 3.5 установить на моем компьютере, он в настоящее время дает:

     bar 1
    foo 0
    baz 42
     

    Подробности:

    Как было предложено в 2012 году Раймондом Хеттингером (см. Письмо на python-dev с темой «Более компактные словари с более быстрой итерацией» ), а теперь (в 2016 году) объявлено в письме Виктором Стэннером на python-dev с темой «Python 3.6 dict становится компактный и получает личную версию, а ключевые слова становятся упорядоченными » из-за исправления /реализации проблемы 27350 « Компактный и упорядоченный диктов » в Python 3.6 теперь мы сможем использовать встроенный dict для поддержания порядка вставки!

    Надеемся, это приведет к реализации тонкого слоя OrderedDict в качестве первого шага. Как указал @ JimFasarakis-Hilliard, некоторые из них видят также случаи использования типа OrderedDict в будущем. Я думаю, что сообщество Python в целом будет тщательно проверять, если это выдержит испытание временем и какие будут следующие шаги.

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

    • Аргументы ключевого слова и
    • (промежуточное) хранилище dict

    Первое, потому что в некоторых случаях облегчает отправку в реализации функций и методов.

    Второй, поскольку он рекомендует более легко использовать dict с в качестве промежуточного хранилища в технологических трубопроводах.

    Раймонд Хеттингер любезно предоставил документацию, объясняющую « The Tech Behind Python 3.6 Dictionaries » - из его презентации в Сан-Франциско Python Meetup Group 2016-DEC-08.

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

    Caveat Emptor (но также см. Ниже обновление 2017-12-15):

    Как @ajcr справедливо отмечает: «Приоритет сохранения этой новой реализации рассматривается как деталь реализации и на нее нельзя положиться». (от whatsnew36 ) не nit сбор, но цитата была отрезана немного пессимистично ;-). Он продолжается как «(это может измениться в будущем, но желательно, чтобы эта новая реализация dict на языке для нескольких выпусков до изменения спецификации языка для мандатной семантики сохранения порядка для всех текущих и будущих реализаций Python, это также помогает сохранить обратную совместимость со старыми версиями языка, где по-прежнему действует случайный порядок итераций, например, Python 3.5) ».

    Так, как и на некоторых человеческих языках (например, на немецком языке), использование формирует язык, и теперь будет объявлена воля ... в whatsnew36 .

    Обновление 2017-12-15:

    В письме к списку python-dev Гвидо ван Россум заявил:

    Сделай это так. «Dict сохраняет порядок вставки» - это решение. Благодаря!

    Итак, версия 3.6 CPython, связанная с заказом вставки dict, теперь становится частью спецификации языка (и больше не является только деталью реализации). Эта почтовая нить также выявила некоторые отличительные цели дизайна для collections.OrderedDict как напомнил Раймонд Хеттингер во время обсуждения.

    ответ дан Dilettant, с репутацией 2424, 10.09.2016
  • 41 рейтинг

    Данный словарь

     e = {1:39, 4:34, 7:110, 2:87}
     

    Сортировка

     sred = sorted(e.items(), key=lambda value: value[1])
     

    результат

     [(4, 34), (1, 39), (2, 87), (7, 110)]
     

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

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

    ответ дан Bishop, с репутацией 2258, 25.01.2016
  • 37 рейтинг

    У меня была та же проблема, и я решил это так:

     WantedOutput = sorted(MyDict, key=lambda x : MyDict[x]) 
     

    (Люди, которые отвечают «Невозможно сортировать дикт», не читали вопрос! На самом деле «я могу сортировать по ключам, но как я могу сортировать на основе значений?», Очевидно, означает, что он хочет получить список ключи отсортированы в соответствии со значением их значений.)

    Обратите внимание, что порядок не определен (ключи с одинаковым значением будут в произвольном порядке в списке вывода).

    ответ дан jimifiki, с репутацией 3276, 18.11.2010
  • 31 рейтинг

    В Python 2.7 просто выполните:

     from collections import OrderedDict
    # regular unsorted dictionary
    d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
    
    # dictionary sorted by key
    OrderedDict(sorted(d.items(), key=lambda t: t[0]))
    OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
    
    # dictionary sorted by value
    OrderedDict(sorted(d.items(), key=lambda t: t[1]))
    OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
     

    copy-paste от: http://docs.python.org/dev/library/collections.html#ordereddict-examples-and-recipes

    Наслаждаться ;-)

    ответ дан sweetdream, с репутацией 795, 22.08.2013
  • 23 рейтинг

    Это код:

     import operator
    origin_list = [
        {"name": "foo", "rank": 0, "rofl": 20000},
        {"name": "Silly", "rank": 15, "rofl": 1000},
        {"name": "Baa", "rank": 300, "rofl": 20},
        {"name": "Zoo", "rank": 10, "rofl": 200},
        {"name": "Penguin", "rank": -1, "rofl": 10000}
    ]
    print ">> Original >>"
    for foo in origin_list:
        print foo
    
    print "\n>> Rofl sort >>"
    for foo in sorted(origin_list, key=operator.itemgetter("rofl")):
        print foo
    
    print "\n>> Rank sort >>"
    for foo in sorted(origin_list, key=operator.itemgetter("rank")):
        print foo
     

    Вот результаты:

    оригинал

     {'name': 'foo', 'rank': 0, 'rofl': 20000}
    {'name': 'Silly', 'rank': 15, 'rofl': 1000}
    {'name': 'Baa', 'rank': 300, 'rofl': 20}
    {'name': 'Zoo', 'rank': 10, 'rofl': 200}
    {'name': 'Penguin', 'rank': -1, 'rofl': 10000}
     

    Rofl

     {'name': 'Baa', 'rank': 300, 'rofl': 20}
    {'name': 'Zoo', 'rank': 10, 'rofl': 200}
    {'name': 'Silly', 'rank': 15, 'rofl': 1000}
    {'name': 'Penguin', 'rank': -1, 'rofl': 10000}
    {'name': 'foo', 'rank': 0, 'rofl': 20000}
     

    Ранг

     {'name': 'Penguin', 'rank': -1, 'rofl': 10000}
    {'name': 'foo', 'rank': 0, 'rofl': 20000}
    {'name': 'Zoo', 'rank': 10, 'rofl': 200}
    {'name': 'Silly', 'rank': 15, 'rofl': 1000}
    {'name': 'Baa', 'rank': 300, 'rofl': 20}
     
    ответ дан PedroMorgan, с репутацией 731, 8.03.2011
  • 22 рейтинг

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

     from collections import Counter
    
    x={'hello':1,'python':5, 'world':3}
    c=Counter(x)
    print c.most_common()
    
    
    >> [('python', 5), ('world', 3), ('hello', 1)]    
     
    ответ дан Ivan Sas, с репутацией 455, 27.06.2012
  • 20 рейтинг

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

     sorted(a_dictionary.values())
     

    предполагая, что производительность не является огромной сделкой.

    ответ дан Hank Gay, с репутацией 50912, 5.03.2009
  • 18 рейтинг

    Вы можете использовать collection.Counter . Обратите внимание: это будет работать как для числовых, так и для нечисловых значений.

     >>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
    >>> from collections import Counter
    >>> #To sort in reverse order
    >>> Counter(x).most_common()
    [(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
    >>> #To sort in ascending order
    >>> Counter(x).most_common()[::-1]
    [(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
    >>> #To get a dictionary sorted by values
    >>> from collections import OrderedDict
    >>> OrderedDict(Counter(x).most_common()[::-1])
    OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])
     
    ответ дан Abhijit, с репутацией 43384, 9.03.2013
  • 18 рейтинг

    Вы можете создать «инвертированный индекс», также

     from collections import defaultdict
    inverse= defaultdict( list )
    for k, v in originalDict.items():
        inverse[v].append( k )
     

    Теперь ваш обратный имеет значения; каждое значение имеет список применимых ключей.

     for k in sorted(inverse):
        print k, inverse[k]
     
    ответ дан S.Lott, с репутацией 309793, 5.03.2009
  • 18 рейтинг

    Попробуйте следующий подход. Определим словарь под названием mydict со следующими данными:

     mydict = {'carl':40,
              'alan':2,
              'bob':1,
              'danny':3}
     

    Если вы хотите отсортировать словарь по клавишам, можно сделать что-то вроде:

     for key in sorted(mydict.iterkeys()):
        print "%s: %s" % (key, mydict[key])
     

    Это должно возвращать следующий результат:

     alan: 2
    bob: 1
    carl: 40
    danny: 3
     

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

     for key, value in sorted(mydict.iteritems(), key=lambda (k,v): (v,k)):
        print "%s: %s" % (key, value)
     

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

     bob: 1
    alan: 2
    danny: 3
    carl: 40
     
    ответ дан Nathaniel Payne, с репутацией 1993, 7.04.2014
  • 14 рейтинг

    Это возвращает список пар ключ-значение в словаре, отсортированный по значению от наивысшего до самого низкого:

     sorted(d.items(), key=lambda x: x[1], reverse=True)
     

    Для словаря, отсортированного по ключу, используйте следующее:

     sorted(d.items(), reverse=True)
     

    Возврат - это список кортежей, потому что сами словари не могут быть отсортированы.

    Это может быть как напечатано, так и отправлено в дальнейшие вычисления.

    ответ дан Zags, с репутацией 11939, 12.02.2014
  • 14 рейтинг

    Вы можете использовать skip dict , словарь которого постоянно сортируется по значению.

     >>> data = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
    >>> SkipDict(data)
    {0: 0.0, 2: 1.0, 1: 2.0, 4: 3.0, 3: 4.0}
     

    Если вы используете keys() , values() или items() вы будете перебирать в отсортированном порядке по значению.

    Он реализован с использованием структуры данных списка пропуска .

    ответ дан malthe, с репутацией 463, 25.09.2014
  • 13 рейтинг
    from django.utils.datastructures import SortedDict
    
    def sortedDictByKey(self,data):
        """Sorted dictionary order by key"""
        sortedDict = SortedDict()
        if data:
            if isinstance(data, dict):
                sortedKey = sorted(data.keys())
                for k in sortedKey:
                    sortedDict[k] = data[k]
        return sortedDict
    
    ответ дан Argun, с репутацией 305, 1.11.2010
  • 12 рейтинг

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

     def dict_val(x):
        return x[1]
    x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
    sorted_x = sorted(x.items(), key=dict_val)
     

    Еще один способ - использовать функцию labmda

     x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
    sorted_x = sorted(x.items(), key=lambda t: t[1])
     
    ответ дан Vishwanath Rawat, с репутацией 307, 25.05.2017
  • 9 рейтинг

    Вот решение, использующее zip на d.values() и d.keys() . Несколько строк вниз по этой ссылке (на объектах View Dictionary):

    Это позволяет создавать пары (значение, ключ), используя zip (): pairs = zip (d.values ​​(), d.keys ()).

    Поэтому мы можем сделать следующее:

     d = {'key1': 874.7, 'key2': 5, 'key3': 8.1}
    
    d_sorted = sorted(zip(d.values(), d.keys()))
    
    print d_sorted 
    # prints: [(5, 'key2'), (8.1, 'key3'), (874.7, 'key1')]
     
    ответ дан Scott, с репутацией 2752, 20.06.2015
  • 7 рейтинг

    Используйте ValueSortedDict из dicts :

     from dicts.sorteddict import ValueSortedDict
    d = {1: 2, 3: 4, 4:3, 2:1, 0:0}
    sorted_dict = ValueSortedDict(d)
    print sorted_dict.items() 
    
    [(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
     
    ответ дан ponty, с репутацией 456, 19.10.2011
  • 6 рейтинг

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

     from collections import OrderedDict
    a = OrderedDict(sorted(originalDict.items(), key = lambda x: x[1]))
     

    Если у вас нет Python 2.7 или выше, лучшее, что вы можете сделать, это перебрать значения в функции генератора. (Существует OrderedDict для 2.4 и 2.6 здесь , но

     a) I don't know about how well it works 
     

    а также

     b) You have to download and install it of course. If you do not have administrative access, then I'm afraid the option's out.)
     

     def gen(originalDict):
        for x,y in sorted(zip(originalDict.keys(), originalDict.values()), key = lambda z: z[1]):
            yield (x, y)
        #Yields as a tuple with (key, value). You can iterate with conditional clauses to get what you want. 
    
    for bleh, meh in gen(myDict):
        if bleh == "foo":
            print(myDict[bleh])
     

    Вы также можете распечатать каждое значение

     for bleh, meh in gen(myDict):
        print(bleh,meh)
     

    Не забудьте удалить скобки после печати, если не используете Python 3.0 или выше

    ответ дан ytpillai, с репутацией 2058, 31.07.2015
  • 6 рейтинг

    Итерируйте через dict и сортируйте его по его значениям в порядке убывания:

     $ python --version
    Python 3.2.2
    
    $ cat sort_dict_by_val_desc.py 
    dictionary = dict(siis = 1, sana = 2, joka = 3, tuli = 4, aina = 5)
    for word in sorted(dictionary, key=dictionary.get, reverse=True):
      print(word, dictionary[word])
    
    $ python sort_dict_by_val_desc.py 
    aina 5
    tuli 4
    joka 3
    sana 2
    siis 1
     
    ответ дан juhoh, с репутацией 61, 30.10.2011
  • 6 рейтинг

    Я придумал этот,

     import operator    
    x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
    sorted_x = {k[0]:k[1] for k in sorted(x.items(), key=operator.itemgetter(1))}
     

    Для Python 3.x: x.items() вместо iteritems() .

     >>> sorted_x
    {0: 0, 1: 2, 2: 1, 3: 4, 4: 3}
     

    Или попробуйте с collections.OrderedDict !

     x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
    from collections import OrderedDict
    
    od1 = OrderedDict(sorted(x.items(), key=lambda t: t[1]))
     
    ответ дан octoback, с репутацией 13234, 8.05.2013
  • 6 рейтинг

    Как отметил Дилетант , Python 3.6 теперь сохранит порядок ! Я думал, что буду использовать функцию, которую я написал, что облегчает сортировку итерации (кортеж, список, dict). В последнем случае вы можете сортировать либо по ключам, либо по значению, и это может учитывать числовое сравнение. Только при> = 3,6!

    Когда вы пытаетесь использовать отсортированную по итерабельному, которая содержит, например, строки, а также ints, sorted () завершится с ошибкой. Конечно, вы можете принудительно провести сравнение строк с str (). Однако в некоторых случаях вы хотите выполнить фактическое числовое сравнение, где 12 меньше 20 (что не соответствует строковому сравнению). Поэтому я придумал следующее. Если вам требуется явное количественное сравнение, вы можете использовать флаг num_as_num который будет пытаться выполнять явную количественную сортировку, пытаясь преобразовать все значения в float. Если это удастся, оно будет выполнять числовую сортировку, иначе оно будет использоваться для сравнения строк.

    Комментарии для улучшения или push-запросы приветствуются.

     def sort_iterable(iterable, sort_on=None, reverse=False, num_as_num=False):
        def _sort(i):
          # sort by 0 = keys, 1 values, None for lists and tuples
          try:
            if num_as_num:
              if i is None:
                _sorted = sorted(iterable, key=lambda v: float(v), reverse=reverse)
              else:
                _sorted = dict(sorted(iterable.items(), key=lambda v: float(v[i]), reverse=reverse))
            else:
              raise TypeError
          except (TypeError, ValueError):
            if i is None:
              _sorted = sorted(iterable, key=lambda v: str(v), reverse=reverse)
            else:
              _sorted = dict(sorted(iterable.items(), key=lambda v: str(v[i]), reverse=reverse))
    
          return _sorted
    
        if isinstance(iterable, list):
          sorted_list = _sort(None)
          return sorted_list
        elif isinstance(iterable, tuple):
          sorted_list = tuple(_sort(None))
          return sorted_list
        elif isinstance(iterable, dict):
          if sort_on == 'keys':
            sorted_dict = _sort(0)
            return sorted_dict
          elif sort_on == 'values':
            sorted_dict = _sort(1)
            return sorted_dict
          elif sort_on is not None:
            raise ValueError(f"Unexpected value {sort_on} for sort_on. When sorting a dict, use key or values")
        else:
          raise TypeError(f"Unexpected type {type(iterable)} for iterable. Expected a list, tuple, or dict")
     
    ответ дан Bram Vanroy, с репутацией 12429, 2.03.2018
  • 6 рейтинг

    Вы можете использовать отсортированную функцию Python

    sorted(iterable[, cmp[, key[, reverse]]])

    Таким образом, вы можете использовать:

    sorted(dictionary.items(),key = lambda x :x[1])

    Перейдите по этой ссылке для получения дополнительной информации о отсортированной функции: https://docs.python.org/2/library/functions.html#sorted

    ответ дан kkk, с репутацией 1040, 21.11.2014
  • 5 рейтинг

    Если ваши значения являются целыми числами, и вы используете Python 2.7 или новее, вы можете использовать collections.Counter вместо dict . Метод most_common предоставит вам все элементы, отсортированные по значению.

    ответ дан Petr Viktorin, с репутацией 40704, 24.01.2012
  • 5 рейтинг

    Это работает в 3.1.x:

     import operator
    slovar_sorted=sorted(slovar.items(), key=operator.itemgetter(1), reverse=True)
    print(slovar_sorted)
     
    ответ дан iFail, с репутацией 59, 16.11.2011
  • 5 рейтинг

    Для полноты, я отправляю решение, используя heapq . Обратите внимание: этот метод будет работать как для числовых, так и для нечисловых значений

     >>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
    >>> x_items = x.items()
    >>> heapq.heapify(x_items)
    >>> #To sort in reverse order
    >>> heapq.nlargest(len(x_items),x_items, operator.itemgetter(1))
    [(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
    >>> #To sort in ascending order
    >>> heapq.nsmallest(len(x_items),x_items, operator.itemgetter(1))
    [(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
     
    ответ дан Abhijit, с репутацией 43384, 23.03.2013
  • 3 рейтинг
    months = {"January": 31, "February": 28, "March": 31, "April": 30, "May": 31,
              "June": 30, "July": 31, "August": 31, "September": 30, "October": 31,
              "November": 30, "December": 31}
    
    def mykey(t):
        """ Customize your sorting logic using this function.  The parameter to
        this function is a tuple.  Comment/uncomment the return statements to test
        different logics.
        """
        return t[1]              # sort by number of days in the month
        #return t[1], t[0]       # sort by number of days, then by month name
        #return len(t[0])        # sort by length of month name
        #return t[0][-1]         # sort by last character of month name
    
    
    # Since a dictionary can't be sorted by value, what you can do is to convert
    # it into a list of tuples with tuple length 2.
    # You can then do custom sorts by passing your own function to sorted().
    months_as_list = sorted(months.items(), key=mykey, reverse=False)
    
    for month in months_as_list:
        print month
    
    ответ дан lessthanl0l, с репутацией 487, 13.02.2014
  • 3 рейтинг

    Из-за требований сохранения обратной совместимости со старыми версиями Python я считаю, что решение OrderedDict очень неразумно. Вы хотите что-то, что работает с версиями Python 2.7 и более ранних версий.

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

    Я не согласен с выбором номер один, представленным в другом ответе, потому что он отбрасывает ключи.

    Я использовал упомянутое выше решение (код, показанный ниже), и сохранил доступ к обеим ключам и значениям, и в моем случае порядок был для значений, но важно было упорядочить клавиши после заказа значений.

     from collections import Counter
    
    x = {'hello':1, 'python':5, 'world':3}
    c=Counter(x)
    print c.most_common()
    
    
    >> [('python', 5), ('world', 3), ('hello', 1)]
     
    ответ дан Eamonn Kenny, с репутацией 757, 3.03.2014
  • 2 рейтинг

    Использование Python 3.2:

     x = {"b":4, "a":3, "c":1}
    for i in sorted(x.values()):
        print(list(x.keys())[list(x.values()).index(i)])
     
    ответ дан raton, с репутацией 311, 3.11.2012
  • 2 рейтинг

    Только что выучили соответствующее умение от Python для всех .

    Вы можете использовать временный список, чтобы помочь вам отсортировать словарь:

     #Assume dictionary to be:
    d = {'apple': 500.1, 'banana': 1500.2, 'orange': 1.0, 'pineapple': 789.0}
    
    # create a temporary list
    tmp = []
    
    # iterate through the dictionary and append each tuple into the temporary list 
    for key, value in d.items():
        tmptuple = (value, key)
        tmp.append(tmptuple)
    
    # sort the list in ascending order
    tmp = sorted(tmp)
    
    print (tmp)
     

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

     tmp = sorted(tmp, reverse=True)
     

    Используя понимание списка, одним слоем будет:

     #Assuming the dictionary looks like
    d = {'apple': 500.1, 'banana': 1500.2, 'orange': 1.0, 'pineapple': 789.0}
    #One liner for sorting in ascending order
    print (sorted([(v, k) for k, v in d.items()]))
    #One liner for sorting in descending order
    print (sorted([(v, k) for k, v in d.items()], reverse=True))
     

    Результат выборки:

     #Asending order
    [(1.0, 'orange'), (500.1, 'apple'), (789.0, 'pineapple'), (1500.2, 'banana')]
    #Descending order
    [(1500.2, 'banana'), (789.0, 'pineapple'), (500.1, 'apple'), (1.0, 'orange')]
     
    ответ дан mcgag, с репутацией 50, 27.05.2018
  • 1 рейтинг

    Этот метод не будет использовать лямбда и хорошо работает на Python 3.6:

      # sort dictionary by value
    d = {'a1': 'fsdfds', 'g5': 'aa3432ff', 'ca':'zz23432'}
    def getkeybyvalue(d,i):
        for k, v in d.items():
            if v == i:
                return (k)
    
    sortvaluelist = sorted(d.values())
    
    # In >> Python 3.6+ << the INSERTION-ORDER of a dict is preserved. That is,
    # when creating a NEW dictionary and filling it 'in sorted order',
    # that order will be maintained.
    sortresult ={}
    for i1 in sortvaluelist:   
        key = getkeybyvalue(d,i1)
        sortresult[key] = i1
    print ('=====sort by value=====')
    print (sortresult)
    print ('=======================')
     
    ответ дан xiyurui, с репутацией 101, 24.05.2017
  • 0 рейтинг
     >>> import collections
    >>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
    >>> sorted_x = collections.OrderedDict(sorted(x.items(), key=lambda t:t[1]))
    >>> OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])
     

    OrderedDict является подклассом dict

    ответ дан liuzhijun, с репутацией 1804, 14.02.2014
  • 0 рейтинг

    Начиная с Python 3.6, теперь упорядочиваются dict объектов. Это официально в спецификации Python 3.7.

     >>> words = {"python": 2, "blah": 4, "alice": 3}
    >>> dict(sorted(words.items(), key=lambda x: x[1]))
    {'python': 2, 'alice': 3, 'blah': 4}
     

    До этого вам пришлось использовать OrderedDict .

    ответ дан Maxime Chéramy, с репутацией 8991, 15.09.2018
  • 0 рейтинг

    Томас Кокелаер объясняет это очень изящно. Я хотел бы упомянуть краткую заметку о его статье.

    Рассмотрим следующий словарь.

     d = {"Pierre": 42, "Anne": 33, "Zoe": 24}
     

    Для сортировки на основе значений представлены следующие подходы.

    sorted и operator модуля

     import operator
    sorted_d = sorted(d.items(), key=operator.itemgetter(1))
     


    sorted функции и lambda функций

     sorted_d = sorted(d.items(), key=lambda x: x[1])
     


    sorted и вернуть упорядоченный словарь

    В предыдущих методах возвращаемые объекты представляют собой список кортежей. Поэтому у нас больше нет словаря. Мы можем использовать OrderedDict если мы предпочитаем.

     from collections import OrderedDict
    sorted_d  = OrderedDict(sorted(d.items(), key=lambda x: x[1]))
     


    sorted функция и понимание списка

     sorted_d = sorted((value, key) for (key,value) in d.items())
     

    Тем не менее, он также сделал быстрый ориентир вышеуказанной процедуры.

    ответ дан iPython, с репутацией 737, 14.07.2018
  • -2 рейтинг

    Я обнаружил, что следующая функция работает хорошо по сравнению с другими опубликованными решениями даже на больших словарях.

     vsort = lambda d: sorted(d.iteritems(), key=lambda (k, v): v)
     

    Пример:

     data = {}
    for i in range(10):
        data[i] = i if i % 2  else -i
    
    print 'Original'
    for k, v in data.items():
        print "k: %s v: %s" % (k, v)
    print ''
    
    print 'Value-sorted'
    for k, v in vsort(data):
        print "k: %s v: %s" % (k, v)
    print ''
     

    Вывод:

     Original
    k: 0 v: 0
    k: 1 v: 1
    k: 2 v: -2
    k: 3 v: 3
    k: 4 v: -4
    k: 5 v: 5
    k: 6 v: -6
    k: 7 v: 7
    k: 8 v: -8
    k: 9 v: 9
    
    Value-sorted
    k: 8 v: -8
    k: 6 v: -6
    k: 4 v: -4
    k: 2 v: -2
    k: 0 v: 0
    k: 1 v: 1
    k: 3 v: 3
    k: 5 v: 5
    k: 7 v: 7
    k: 9 v: 9
     

    Пример кода синхронизации:

     import numpy as np
    from time import time
    import operator
    np.random.seed(0)
    
    N = int(1e6)
    x = {i: np.random.random() for i in xrange(N)}
    
    t0 = -time()
    sorted_0 = sorted(x.items(), key=operator.itemgetter(1))
    t0 += time()
    
    t1 = -time()
    sorted_1 = vsort(x)
    t1 += time()
    
    print 'operator-sort: %f vsort: %f' % (t0, t1)
    print sorted_0[:3]
    print sorted_1[:3]
     

    Вывод:

     operator-sort: 2.041510 vsort: 1.692324
    [(661553, 7.071203171893359e-07), (529124, 1.333679640169727e-06), (263972, 2.9504162779581122e-06)]
    [(661553, 7.071203171893359e-07), (529124, 1.333679640169727e-06), (263972, 2.9504162779581122e-06)]
     
    ответ дан skillman, с репутацией 68, 29.07.2015