W pythonie, zarówno dict {1:1,2:2,3:3} i {3:3,2:2,1:1} produkuje "{1:1,2:2,3:3}", gdy str () 'd?

Czy mogę polegać na tym sortowaniu, a przynajmniej na tym, że dyktury zawierające ten sam klucz / ValuePairs wygenerują ten sam ciąg po uruchomieniu funkcji STR ()?

7
bigblind 28 listopad 2011, 01:57

4 odpowiedzi

Najlepsza odpowiedź

Możesz polegać ani z tych dwóch właściwości. Kolejność słownika po przekonwertowaniu na łańcuch zależy również od kolejności wprowadzania par kluczy / wartości.

Z odrobiną znajomości kodu źródłowego Pythona (oglądać Potężny słownik z Pycon 2010), lub trochę próby i błędu, możesz łatwo znaleźć licznik przykłady:

>>> {1: 1, 9: 9}
{1: 1, 9: 9}
>>> {9: 9, 1: 1}
{9: 9, 1: 1}
7
Andrew Dalke 27 listopad 2011, 22:27

Wbudowany typ dict nie gwarantuje żadnej konkretnej kolejności kluczy.

Nawet jeśli wydaje się, że zawsze otrzymasz ten sam ciąg, nie polegaj na tym. Jeśli to zrobisz, gdy aktualizujesz Pythona, może być zmiana w implementacji, która powoduje, że twoje założenie nie powiedzie się.

ZamówionedDik Czy zapewnia gwarancje na temat kolejność kluczy.

4
Andrew Dalke 27 listopad 2011, 22:23

Nie, Nie możesz polegać na tym . Jak wspomniano w Edukacja Pythona. 4. edycja według Mark Lutz (strona 94.):

(...) Ponieważ słowniki nie są sekwencjami, nie utrzymują żadnych niezawodny porządek od lewej do prawej . Oznacza to, że jeśli wykonamy słownikowy i wydrukuj go Powrót, jego klucze mogą wrócić w innym porządku , niż w którym ich wpisaliśmy (...)

Jednak książka wspomina inne rozwiązanie do drukowania par kluczowych par w kolejności kluczy (D jest słownikiem, który chcesz przedstawić):

>>> for key in sorted(D):
    print(key, '=>', D[key])

Korzystając z powyższego, możesz drukować przedmioty w dowolny sposób, lub nawet tworzyć pewną sekwencję zawierającą zamówione elementy, takie jak:

>>> D = {'a': 12, 'b': 65, 7: 'asd'}
>>> S = [(key, D[key]) for key in sorted(D)]
>>> S
[(7, 'asd'), ('a', 12), ('b', 65)]

Gdzie kolejność elementów w S jest niezawodny (możesz polegać na niej, ponieważ nie zmienia się, dopóki nie zmieniysz go).

2
Tadeck 27 listopad 2011, 22:10

Nie, nie możesz. Spróbuj tego:

{ i:i for i in range(0, 100, 10) }

Powodem, dla którego działa w przypadku ciągłych liczb całkowitych, począwszy od zera, jest to, że każda hazeger w sobie (hash(i) == i) i słowniki będą wielkości ich wewnętrzne tabele, które mają być co najmniej tak duże, jak trzymane elementy (używają strategii sondowania (używają strategii sondowej, która wymaga tego). W konsekwencji, integer i kończy się w slocie {x2}} bez kolizji. Znajdziesz również, że ciągłe liczby całkowite zaczynające się na niektórych liczbie, które mają być monotonicznie rosnące, ale mogą rzucać gdzieś w środku:

>>> { i:'' for i in range(25, 35) }
{32: '', 33: '', 34: '', 25: '', 26: '', 27: '', 28: '', 29: '', 30: '', 31: ''}

Ważne jest, aby pamiętać, że są one jedynie obserwacjami rzeczywistych zachowań. Nic w języku gwarantuje z tego, więc nie możesz na tym polegać.

2
Marcelo Cantos 27 listopad 2011, 22:17