3413 Stimmen

Wie kann ich ein Wörterbuch nach Wert sortieren?

Ich habe ein Wörterbuch mit Werten, die aus zwei Feldern in einer Datenbank gelesen werden: ein Zeichenfolgenfeld und ein numerisches Feld. Das String-Feld ist eindeutig, daher ist es der Schlüssel des Wörterbuchs.

Ich kann nach den Schlüsseln sortieren, aber wie kann ich nach den Werten sortieren?

Hinweis: Ich habe die Stack Overflow-Frage hier gelesen Wie kann ich eine Liste von Wörterbüchern nach einem Wert des Wörterbuchs sortieren? und könnte wahrscheinlich meinen Code ändern, um eine Liste von Wörterbüchern zu haben, aber da ich nicht wirklich eine Liste von Wörterbüchern brauche, wollte ich wissen, ob es eine einfachere Lösung gibt, um entweder in aufsteigender oder absteigender Reihenfolge zu sortieren.

17voto

rassa45 Punkte 3400

Denken Sie natürlich daran, dass Sie die OrderedDict weil normale Python-Wörterbücher die ursprüngliche Reihenfolge nicht beibehalten.

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

Wenn Sie nicht über Python 2.7 oder höher verfügen, können Sie bestenfalls über die Werte in einer Generatorfunktion iterieren. (Es gibt eine OrderedDict für 2.4 und 2.6 aquí aber

a) Ich weiß nicht, wie gut es funktioniert

und

b) Sie müssen es natürlich herunterladen und installieren. Wenn Sie keinen administrativen Zugang haben, ist diese Möglichkeit leider nicht gegeben).


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])

Sie können auch jeden Wert ausdrucken

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

Bitte denken Sie daran, die Klammern nach print zu entfernen, wenn Sie nicht Python 3.0 oder höher verwenden

15voto

Argun Punkte 417
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

15voto

Scott Punkte 5523

Hier ist eine Lösung mit zip auf d.values() y d.keys() . Ein paar Zeilen weiter unten ist dieser Link (auf Dictionary view objects):

Dies ermöglicht die Erstellung von Paaren (Wert, Schlüssel) mit zip(): pairs = zip(d.values(), d.keys()).

Wir können also wie folgt vorgehen:

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')]

14voto

mcgag Punkte 185

Ich habe gerade eine entsprechende Fähigkeit von Python für jedermann .

Sie können eine vorläufige Liste verwenden, die Ihnen bei der Sortierung des Wörterbuchs hilft:

#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)

Wenn Sie die Liste in absteigender Reihenfolge sortieren möchten, ändern Sie einfach die ursprüngliche Sortierzeile in:

tmp = sorted(tmp, reverse=True)

Beim Verstehen von Listen würde der Einzeiler lauten:

#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))

Beispielhafte Ausgabe:

#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')]

14voto

Bram Vanroy Punkte 24741

Wie von Dilettant hervorgehoben wird Python 3.6 nun die Ordnung aufrechterhalten ! Ich dachte, ich würde eine Funktion teilen, die ich geschrieben habe und die das Sortieren einer Iterablen (Tupel, Liste, Diktat) erleichtert. Im letzteren Fall können Sie entweder auf Schlüssel oder Werte sortieren, und es kann numerischen Vergleich zu berücksichtigen. Nur für >= 3.6!

Wenn Sie versuchen, sorted auf eine Iterable anzuwenden, die z.B. sowohl Strings als auch Ints enthält, wird sorted() fehlschlagen. Natürlich können Sie den String-Vergleich mit str() erzwingen. In einigen Fällen möchten Sie jedoch Folgendes tun aktuell numerischer Vergleich, wobei 12 kleiner ist als 20 (was beim String-Vergleich nicht der Fall ist). Also habe ich mir folgendes ausgedacht. Wenn Sie einen expliziten numerischen Vergleich wünschen, können Sie das Flag num_as_num die versucht, eine explizite numerische Sortierung vorzunehmen, indem sie versucht, alle Werte in Fließkommazahlen umzuwandeln. Wenn dies gelingt, wird eine numerische Sortierung durchgeführt, andernfalls wird auf einen String-Vergleich zurückgegriffen.

Kommentare zur Verbesserung sind willkommen.

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")

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X