Za pomocą PyCharm zauważyłem, że oferuje konwersję dosłownego słownika :
d = {
'one': '1',
'two': '2',
}
w konstruktora nagrań :
d = dict(one='1', two='2')
Czy te różne podejścia różnią się w jakiś znaczący sposób?
(Pisząc to pytanie zauważyłem, że użycie dict()
klucza numerycznego wydaje się niemożliwe ... d = {1: 'one', 2: 'two'}
jest możliwe, ale oczywiście dict(1='one' ...)
nie jest. Coś jeszcze?)
python
dictionary
pycharm
maligree
źródło
źródło
dict()
pobiera listę par klucz-wartość, a także zezwala na nazwane parametry, dzięki czemu można go używać do tworzenia dowolnego typu dykt, ale nie ze składnią, której używasz. Prawdopodobnie nie jest również nic warte, że w pyCharm wystąpił błąd ( youtrack.jetbrains.net/issue/PY-2512 ), szczególnie z powodu tego, co odkryłeś, co zostało naprawione).dict(abc = 123)
konstruktor tworzy słownik z kluczami bajt-ciąg'abc'
, co może być zaskakujące, jeśli używaszunicode_literals
i spodziewasz się, że klucze słownika będą Unicodeu'abc'
. Zobacz stackoverflow.com/questions/20357210/... .Odpowiedzi:
Myślę, że wskazałeś najbardziej oczywistą różnicę. Oprócz tego,
pierwszy nie musi wyszukiwać,
dict
co powinno nieco przyspieszyćdrugi patrzy
dict
wlocals()
czymglobals()
i odnajduje wbudowane, więc można przełączyć zachowań poprzez zdefiniowanie lokalnego o nazwiedict
na przykład, choć nie mogę myśleć o gdziekolwiek to będzie dobry pomysł, oprócz być może podczas debugowaniaźródło
Dosłowność jest znacznie szybsza, ponieważ wykorzystuje zoptymalizowane kody BUILD_MAP i STORE_MAP zamiast ogólnych CALL_FUNCTION:
źródło
Wyglądają prawie tak samo w Pythonie 3.2.
Jak wskazał gnibbler, pierwszy nie musi wyszukiwać
dict
, co powinno nieco przyspieszyć.źródło
$ pypy -m perf timeit -l '1000000' -n '5' -s 'i=(("a",1), ("b", 2), ("c", 3))' "{'a': 1, 'b': 2, 'c': 3}" ....... Mean +- std dev: 1.73 ns +- 0.14 ns $ pypy -m perf timeit -l '1000000' -n '5' -s 'i=(("a",1), ("b", 2), ("c", 3))' '{k:v for k,v in i}' ....... Mean +- std dev: 139 ns +- 10 ns $ pypy -m perf timeit -l '1000000' -n '5' -s 'i=(("a",1), ("b", 2), ("c", 3))' 'dict(i)' ....... Mean +- std dev: 188 ns +- 16 ns
Te dwa podejścia dają identyczne słowniki, z wyjątkiem, jak zauważyłeś, gdzie zakłócają się reguły leksykalne Pythona.
Dosłowne słowniki są nieco bardziej oczywistymi słownikami i możesz stworzyć dowolny klucz, ale musisz podać nazwy kluczy. Z drugiej strony możesz użyć zmiennych dla kluczy, jeśli z jakiegoś powodu potrzebujesz:
dict()
Konstruktor daje większą elastyczność ze względu na różnorodność form wejścia przez nią działań. Na przykład możesz podać iterator par, który będzie traktował je jako pary klucz / wartość.Nie mam pojęcia, dlaczego PyCharm zaoferowałby konwersję jednej formy na drugą.
źródło
Jedną dużą różnicą w przypadku Pythona 3.4 + pycharm jest to, że konstruktor dict () generuje komunikat „błąd składni”, jeśli liczba kluczy przekracza 256.
Wolę teraz używać literału dict.
źródło
Z samouczka Python 2.7:
Podczas:
Zatem zarówno {}, jak i dict () tworzą słownik, ale zapewniają nieco inne sposoby inicjowania danych słownikowych.
źródło
Uważam, że dosłowny słownik
d = {'one': '1'}
jest znacznie bardziej czytelny, ponieważ definiujesz dane, zamiast przypisywać wartości i wysyłać je dodict()
konstruktora.Z drugiej strony widziałem, jak ludzie błędnie wpisują dosłowny słownik, ponieważ
d = {'one', '1'}
we współczesnym Pythonie 2.7+ stworzy zestaw.Mimo to nadal wolę na wszelkie sposoby korzystać z zestawu literału, ponieważ myślę, że jest to bardziej czytelna, osobista preferencja.
źródło
set
istnieje dosłowna składnia dla s. Chciałbym, żeby istniała dosłowna składnia dla uporządkowanych dykt ... całkiem pewna, że używam ich częściej niż zbiorów.literał dict () jest przydatny, gdy kopiujesz wklejanie wartości z czegoś innego (brak pytona) Na przykład z listy zmiennych środowiskowych. powiedzmy, jeśli masz plik bash
możesz łatwo wkleić następnie do
dict()
literału i dodać komentarze. Ułatwia także odwrotne kopiowanie do czegoś innego. Podczas gdy{'FOO': 'bar'}
składnia jest dość unikalna dla Pythona i Jsona. Więc jeśli często używasz Jsona, możesz chcieć używać{}
literałów z podwójnymi cudzysłowami.źródło
Nie ma literału-dyktu do tworzenia klas dziedziczonych przez dyk, niestandardowych klas-dykt z dodatkowymi metodami. W takim przypadku należy użyć niestandardowego konstruktora klasy dict, na przykład:
źródło
Weź również pod uwagę fakt, że tokenów pasujących do operatorów nie można używać w składni konstruktora, tj. Klucze przerywane.
źródło