Jaki byłby to dobry sposób, aby przejść od {2:3, 1:89, 4:5, 3:0}
do {1:89, 2:3, 3:0, 4:5}
?
Sprawdziłem niektóre posty, ale wszystkie używają operatora „posortowanego”, który zwraca krotki.
Jaki byłby to dobry sposób, aby przejść od {2:3, 1:89, 4:5, 3:0}
do {1:89, 2:3, 3:0, 4:5}
?
Sprawdziłem niektóre posty, ale wszystkie używają operatora „posortowanego”, który zwraca krotki.
Odpowiedzi:
Standardowe słowniki w języku Python są nieuporządkowane. Nawet jeśli posortujesz pary (klucz, wartość), nie będziesz w stanie przechowywać ich w dict
sposób, który zachowałby porządek.
Najprostszym sposobem jest użycie OrderedDict
, które pamięta kolejność wstawiania elementów:
In [1]: import collections
In [2]: d = {2:3, 1:89, 4:5, 3:0}
In [3]: od = collections.OrderedDict(sorted(d.items()))
In [4]: od
Out[4]: OrderedDict([(1, 89), (2, 3), (3, 0), (4, 5)])
Nieważne, jak od
jest wydrukowany; będzie działać zgodnie z oczekiwaniami:
In [11]: od[1]
Out[11]: 89
In [12]: od[3]
Out[12]: 0
In [13]: for k, v in od.iteritems(): print k, v
....:
1 89
2 3
3 0
4 5
W przypadku użytkowników Python 3 należy użyć .items()
zamiast .iteritems()
:
In [13]: for k, v in od.items(): print(k, v)
....:
1 89
2 3
3 0
4 5
sorted_dict = dict(sorted(unsorted_dict.items()))
Same słowniki nie mają jako takich uporządkowanych elementów, jeśli chcesz je wydrukować itp. W określonym porządku, oto kilka przykładów:
W Pythonie 2.4 i nowszych:
mydict = {'carl':40,
'alan':2,
'bob':1,
'danny':3}
for key in sorted(mydict):
print "%s: %s" % (key, mydict[key])
daje:
alan: 2
bob: 1
carl: 40
danny: 3
(Python poniżej 2.4 :)
keylist = mydict.keys()
keylist.sort()
for key in keylist:
print "%s: %s" % (key, mydict[key])
Źródło: http://www.saltycrane.com/blog/2007/09/how-to-sort-python-dictionary-by-keys/
for key, value in sorted(mydict.items())"
Z dokumentacji biblioteki Pythonacollections
:
>>> from collections import OrderedDict
>>> # regular unsorted dictionary
>>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
>>> # dictionary sorted by key -- OrderedDict(sorted(d.items()) also works
>>> 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)])
>>> # dictionary sorted by length of the key string
>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])
reverse=True
np.OrderedDict(sorted(d.items(), reverse=True, key=lambda t: t[0]))
Unexpected type(s): (List[str]) Possible types: (Mapping) (Iterable[Tuple[Any, Any]])
W przypadku CPython / PyPy 3.6 i dowolnego Pythona 3.7 lub nowszego można to łatwo zrobić za pomocą:
>>> d = {2:3, 1:89, 4:5, 3:0}
>>> dict(sorted(d.items()))
{1: 89, 2: 3, 3: 0, 4: 5}
{key:d[key] for key in sorted(d.keys())}
Istnieje wiele modułów Python, które zapewniają implementacje słownikowe, które automatycznie utrzymują klucze w posortowanej kolejności. Rozważ moduł sortedcontainers , który jest implementacją czysto Python i Fast-as-C. Istnieje również porównanie wydajności z innymi popularnymi opcjami porównanymi ze sobą.
Korzystanie z zamówionego dykta jest nieodpowiednim rozwiązaniem, jeśli trzeba stale dodawać i usuwać pary klucz / wartość, a także iterować.
>>> from sortedcontainers import SortedDict
>>> d = {2:3, 1:89, 4:5, 3:0}
>>> s = SortedDict(d)
>>> s.items()
[(1, 89), (2, 3), (3, 0), (4, 5)]
Typ SortedDict obsługuje również indeksowane wyszukiwanie i usuwanie lokalizacji, co nie jest możliwe w przypadku wbudowanego typu dict.
>>> s.iloc[-1]
4
>>> del s.iloc[2]
>>> s.keys()
SortedSet([1, 2, 4])
Po prostu:
d = {2:3, 1:89, 4:5, 3:0}
sd = sorted(d.items())
for k,v in sd:
print k, v
Wynik:
1 89
2 3
3 0
4 5
sd
to lista krotek, a nie słownik. (wciąż przydatne).
Jak wspomnieli inni, słowniki są z natury nieuporządkowane. Jeśli jednak problemem jest jedynie wyświetlanie słowników w uporządkowany sposób, można zastąpić __str__
metodę w podklasie słownika i użyć tej klasy słownika zamiast wbudowanej dict
. Na przykład.
class SortedDisplayDict(dict):
def __str__(self):
return "{" + ", ".join("%r: %r" % (key, self[key]) for key in sorted(self)) + "}"
>>> d = SortedDisplayDict({2:3, 1:89, 4:5, 3:0})
>>> d
{1: 89, 2: 3, 3: 0, 4: 5}
Zauważ, że nie zmienia to niczego w sposobie przechowywania kluczy, kolejności, w której powrócą podczas iteracji nad nimi itp., W jaki sposób są wyświetlane za pomocą print
lub w konsoli Pythona.
Znaleziono inny sposób:
import json
print json.dumps(d, sort_keys = True)
upd:
1. sortuje również zagnieżdżone obiekty (dzięki @DanielF).
2. Słowniki python są nieuporządkowane, dlatego można je drukować lub przypisywać tylko do str.
W Python 3.
>>> D1 = {2:3, 1:89, 4:5, 3:0}
>>> for key in sorted(D1):
print (key, D1[key])
daje
1 89
2 3
3 0
4 5
Słownik Pythona był nieuporządkowany przed Pythonem 3.6. W implementacji CPython w Pythonie 3.6 słownik zachowuje kolejność wstawiania. Od wersji Python 3.7 będzie to funkcja językowa.
W dzienniku zmian Pythona 3.6 ( https://docs.python.org/3.6/whatsnew/3.6.html#whatsnew36-compactdict ):
Aspekt zachowywania porządku w tej nowej implementacji jest uważany za szczegół implementacji i nie należy na nim polegać (może się to zmienić w przyszłości, ale pożądane jest, aby ta nowa implementacja dict w języku była dostępna przez kilka wydań przed zmianą specyfikacji języka narzucenie semantyki zachowującej porządek dla wszystkich bieżących i przyszłych implementacji Pythona; pomaga to również zachować zgodność wsteczną ze starszymi wersjami języka, w którym nadal obowiązuje kolejność losowych iteracji, np. Python 3.5).
W dokumencie Python 3.7 ( https://docs.python.org/3.7/tutorial/datastructures.html#dictionaries ):
Wykonywanie listy (d) w słowniku zwraca listę wszystkich kluczy używanych w słowniku, w kolejności wstawiania (jeśli chcesz go posortować, po prostu użyj sorted (d)).
Tak więc, w przeciwieństwie do poprzednich wersji, możesz posortować słownik po Pythonie 3.6 / 3.7. Jeśli chcesz posortować zagnieżdżony dykt, w tym sub-dykt wewnątrz, możesz:
test_dict = {'a': 1, 'c': 3, 'b': {'b2': 2, 'b1': 1}}
def dict_reorder(item):
return {k: sort_dict(v) if isinstance(v, dict) else v for k, v in sorted(item.items())}
reordered_dict = dict_reorder(test_dict)
https://gist.github.com/ligyxy/f60f0374defc383aa098d44cfbd318eb
Tutaj znalazłem najprostsze rozwiązanie do sortowania słownika python według klucza za pomocą pprint
. na przykład.
>>> x = {'a': 10, 'cd': 20, 'b': 30, 'az': 99}
>>> print x
{'a': 10, 'b': 30, 'az': 99, 'cd': 20}
ale podczas używania pprint zwróci posortowane dict
>>> import pprint
>>> pprint.pprint(x)
{'a': 10, 'az': 99, 'b': 30, 'cd': 20}
Istnieje prosty sposób na posortowanie słownika.
Zgodnie z twoim pytaniem
Rozwiązaniem jest :
c={2:3, 1:89, 4:5, 3:0}
y=sorted(c.items())
print y
(Gdzie c to nazwa twojego słownika.)
Ten program daje następujące dane wyjściowe:
[(1, 89), (2, 3), (3, 0), (4, 5)]
tak jak chciałeś.
Innym przykładem jest:
d={"John":36,"Lucy":24,"Albert":32,"Peter":18,"Bill":41}
x=sorted(d.keys())
print x
Daje wynik:['Albert', 'Bill', 'John', 'Lucy', 'Peter']
y=sorted(d.values())
print y
Daje wynik:[18, 24, 32, 36, 41]
z=sorted(d.items())
print z
Daje wynik:
[('Albert', 32), ('Bill', 41), ('John', 36), ('Lucy', 24), ('Peter', 18)]
Dlatego zmieniając go w klucze, wartości i elementy, możesz drukować tak, jak chcesz. Mam nadzieję, że to pomaga!
Wygeneruje dokładnie to, co chcesz:
D1 = {2:3, 1:89, 4:5, 3:0}
sort_dic = {}
for i in sorted(D1):
sort_dic.update({i:D1[i]})
print sort_dic
{1: 89, 2: 3, 3: 0, 4: 5}
Ale to nie jest właściwy sposób, aby to zrobić, ponieważ może wykazywać wyraźne zachowanie z różnymi słownikami, których niedawno się nauczyłem. Dlatego w odpowiedzi na moje zapytanie, które tu udostępniam, Tim zaproponował doskonały sposób.
from collections import OrderedDict
sorted_dict = OrderedDict(sorted(D1.items(), key=lambda t: t[0]))
Myślę, że najłatwiej jest posortować dyktowanie według klucza i zapisać posortowaną parę klucz: wartość w nowym dykcie.
dict1 = {'renault': 3, 'ford':4, 'volvo': 1, 'toyota': 2}
dict2 = {} # create an empty dict to store the sorted values
for key in sorted(dict1.keys()):
if not key in dict2: # Depending on the goal, this line may not be neccessary
dict2[key] = dict1[key]
Aby było to jaśniejsze:
dict1 = {'renault': 3, 'ford':4, 'volvo': 1, 'toyota': 2}
dict2 = {} # create an empty dict to store the sorted values
for key in sorted(dict1.keys()):
if not key in dict2: # Depending on the goal, this line may not be neccessary
value = dict1[key]
dict2[key] = value
Możesz utworzyć nowy słownik, sortując aktualny słownik według klucza zgodnie z pytaniem.
To jest twój słownik
d = {2:3, 1:89, 4:5, 3:0}
Utwórz nowy słownik d1, sortując ten d za pomocą funkcji lambda
d1 = dict(sorted(d.items(), key = lambda x:x[0]))
d1 powinno być {1: 89, 2: 3, 3: 0, 4: 5}, posortowane na podstawie kluczy z d.
Dykty w języku Python nie są uporządkowane. Zwykle nie stanowi to problemu, ponieważ najczęstszym przypadkiem użycia jest wyszukiwanie.
Najprostszym sposobem na zrobienie tego, co chcesz, byłoby utworzenie collections.OrderedDict
wstawiania elementów w posortowanej kolejności.
ordered_dict = collections.OrderedDict([(k, d[k]) for k in sorted(d.keys())])
Jeśli potrzebujesz iteracji, jak sugerują inni powyżej, najprostszym sposobem byłoby iterowanie posortowanych kluczy. Przykłady
Wydrukuj wartości posortowane według kluczy:
# create the dict
d = {k1:v1, k2:v2,...}
# iterate by keys in sorted order
for k in sorted(d.keys()):
value = d[k]
# do something with k, value like print
print k, value
Pobierz listę wartości posortowanych według kluczy:
values = [d[k] for k in sorted(d.keys())]
for k,value in sorted(d.items()):
jest lepsze: unika dostępu do dykta po raz kolejny w pętli
Wymyślam sortowanie pojedynczych wierszy.
>> a = {2:3, 1:89, 4:5, 3:0}
>> c = {i:a[i] for i in sorted(a.keys())}
>> print(c)
{1: 89, 2: 3, 3: 0, 4: 5}
[Finished in 0.4s]
Mam nadzieję, że to będzie pomocne.
Ta funkcja posortuje rekursywnie dowolny słownik według jego klucza. Oznacza to, że jeśli jakakolwiek wartość w słowniku jest również słownikiem, również zostanie posortowana według klucza. Jeśli korzystasz z CPython 3.6 lub nowszego, możesz dokonać prostej zmiany, dict
zamiast używania OrderedDict
.
from collections import OrderedDict
def sort_dict(d):
items = [[k, v] for k, v in sorted(d.items(), key=lambda x: x[0])]
for item in items:
if isinstance(item[1], dict):
item[1] = sort_dict(item[1])
return OrderedDict(items)
#return dict(items)
Faceci, których komplikujecie ... to naprawdę proste
from pprint import pprint
Dict={'B':1,'A':2,'C':3}
pprint(Dict)
Dane wyjściowe to:
{'A':2,'B':1,'C':3}
Najprostszym rozwiązaniem jest wyświetlenie listy kluczy do sortowania w kolejności sortowania, a następnie iteracji po dyktowaniu. Na przykład
a1 = {'a':1, 'b':13, 'd':4, 'c':2, 'e':30}
a1_sorted_keys = sorted(a1, key=a1.get, reverse=True)
for r in a1_sorted_keys:
print r, a1[r]
Następujące będzie wyjście (kolejność wycofywania)
e 30
b 13
d 4
c 2
a 1
Porównanie czasowe dwóch metod w 2.7 pokazuje, że są one praktycznie identyczne:
>>> setup_string = "a = sorted(dict({2:3, 1:89, 4:5, 3:0}).items())"
>>> timeit.timeit(stmt="[(k, val) for k, val in a]", setup=setup_string, number=10000)
0.003599141953657181
>>> setup_string = "from collections import OrderedDict\n"
>>> setup_string += "a = OrderedDict({1:89, 2:3, 3:0, 4:5})\n"
>>> setup_string += "b = a.items()"
>>> timeit.timeit(stmt="[(k, val) for k, val in b]", setup=setup_string, number=10000)
0.003581275490432745
from operator import itemgetter
# if you would like to play with multiple dictionaries then here you go:
# Three dictionaries that are composed of first name and last name.
user = [
{'fname': 'Mo', 'lname': 'Mahjoub'},
{'fname': 'Abdo', 'lname': 'Al-hebashi'},
{'fname': 'Ali', 'lname': 'Muhammad'}
]
# This loop will sort by the first and the last names.
# notice that in a dictionary order doesn't matter. So it could put the first name first or the last name first.
for k in sorted (user, key=itemgetter ('fname', 'lname')):
print (k)
# This one will sort by the first name only.
for x in sorted (user, key=itemgetter ('fname')):
print (x)
dictionary = {1:[2],2:[],5:[4,5],4:[5],3:[1]}
temp=sorted(dictionary)
sorted_dict = dict([(k,dictionary[k]) for i,k in enumerate(temp)])
sorted_dict:
{1: [2], 2: [], 3: [1], 4: [5], 5: [4, 5]}
Albo użyj pandas
,
Próbny:
>>> d={'B':1,'A':2,'C':3}
>>> df=pd.DataFrame(d,index=[0]).sort_index(axis=1)
A B C
0 2 1 3
>>> df.to_dict('int')[0]
{'A': 2, 'B': 1, 'C': 3}
>>>
Widzieć:
Moja sugestia jest taka, ponieważ umożliwia sortowanie nagrania lub utrzymywanie go w porządku podczas dodawania elementów i może być konieczne dodanie elementów w przyszłości:
Zbuduj dict
od zera w trakcie pracy. Mają drugą strukturę danych, listę z listą kluczy. Pakiet bisect ma funkcję insort, która umożliwia wstawianie do posortowanej listy lub sortowanie listy po całkowitym zapełnieniu słownika. Teraz, gdy wykonujesz iterację po swoim dyktando, zamiast tego iterujesz po liście, aby uzyskać dostęp do każdego klucza w uporządkowany sposób, nie martwiąc się o reprezentację struktury dykt (która nie została stworzona do sortowania).
l = dict.keys()
l2 = l
l2.append(0)
l3 = []
for repeater in range(0, len(l)):
smallnum = float("inf")
for listitem in l2:
if listitem < smallnum:
smallnum = listitem
l2.remove(smallnum)
l3.append(smallnum)
l3.remove(0)
l = l3
for listitem in l:
print(listitem)