Rozumiem, że oba są zasadniczo tym samym, ale jeśli chodzi o styl, który z nich jest lepszy (bardziej Pythonic) do utworzenia pustej listy lub dyktu?
Rozumiem, że oba są zasadniczo tym samym, ale jeśli chodzi o styl, który z nich jest lepszy (bardziej Pythonic) do utworzenia pustej listy lub dyktu?
Odpowiedzi:
Pod względem szybkości nie ma konkurencji dla pustych list / dykt:
>>> from timeit import timeit
>>> timeit("[]")
0.040084982867934334
>>> timeit("list()")
0.17704233359267718
>>> timeit("{}")
0.033620194745424214
>>> timeit("dict()")
0.1821558326547077
a dla niepustych:
>>> timeit("[1,2,3]")
0.24316302770330367
>>> timeit("list((1,2,3))")
0.44744206316727286
>>> timeit("list(foo)", setup="foo=(1,2,3)")
0.446036018543964
>>> timeit("{'a':1, 'b':2, 'c':3}")
0.20868602015059423
>>> timeit("dict(a=1, b=2, c=3)")
0.47635635255323905
>>> timeit("dict(bar)", setup="bar=[('a', 1), ('b', 2), ('c', 3)]")
0.9028228448029267
Ponadto, użycie notacji z nawiasami kwadratowymi pozwala na użycie list i słowników, co może być wystarczającym powodem.
timeit()
funkcja raportuje całkowity czas wykonania określonej liczby iteracji, co jest 1000000
wartością domyślną. Zatem powyższe przykłady to liczba sekund potrzebna do uruchomienia fragmentu kodu milion razy. Na przykład timeit('dict()', number=1) // -> 4.0531158447265625e-06
(jedna iteracja) podczas timeit('dict()') // -> 0.12412905693054199
(milion iteracji)
Moim zdaniem []
i {}
są najbardziej pytonicznymi i czytelnymi sposobami tworzenia pustych list / dykt.
Uważaj set()
jednak, na przykład:
this_set = {5}
some_other_set = {}
Może być mylące. Pierwsza tworzy zestaw z jednym elementem, druga tworzy pusty dykt, a nie zestaw.
{}
zawsze tworzy pusty dykt. {1,2,3}
tworzy zestaw w wersji 2.7+, ale jest błędem składniowym w 2.6
i starszych wersjach.
some_epic_set
wskazującej na pusty dict
obiekt ... to nie jest pusty zbiór. Aby uzyskać pusty zestaw, musisz użyć set()
.
{5}
tworzy zestaw z jednym elementem 5
i {}
jest pustym nakazem.
{*()}
do zrobienia pustego set
z literałem składni. Nazywam to jednooką małpą operatorem. :-)
Dict dosłowna może być drobny trochę szybciej, jej kod bajtowy jest krótszy:
In [1]: import dis
In [2]: a = lambda: {}
In [3]: b = lambda: dict()
In [4]: dis.dis(a)
1 0 BUILD_MAP 0
3 RETURN_VALUE
In [5]: dis.dis(b)
1 0 LOAD_GLOBAL 0 (dict)
3 CALL_FUNCTION 0
6 RETURN_VALUE
To samo dotyczy list
vs[]
CALL_FUNCTION
zajmuje co najmniej tyle samo czasu, ile BUILD_MAP
(wywoływana funkcja zasadniczo jest BUILD_MAP
), a LOAD_GLOBAL
trwa to tylko dodatkowe obciążenie.
IMHO, używanie list()
i dict()
sprawia, że twój Python wygląda jak C. Ugh.
W przypadku różnicy między [] i list () istnieje pułapka, na którą nie widziałem nikogo innego. Jeśli użyjesz słownika jako członka listy, oba dadzą zupełnie inne wyniki:
In [1]: foo_dict = {"1":"foo", "2":"bar"}
In [2]: [foo_dict]
Out [2]: [{'1': 'foo', '2': 'bar'}]
In [3]: list(foo_dict)
Out [3]: ['1', '2']
[foo_dict]
przy użyciu list((foo_dict,))
. list()
Metoda bierze iterable jak to tylko parametr i iteracje nad nim, aby dodać elementy do listy. Spowoduje to podobną pułapkę, jeśli list(some_list)
spowoduje to spłaszczenie listy.
list () i [] działają inaczej:
>>> def a(p=None):
... print(id(p))
...
>>> for r in range(3):
... a([])
...
139969725291904
139969725291904
139969725291904
>>> for r in range(3):
... a(list())
...
139969725367296
139969725367552
139969725367616
list () zawsze tworzy nowy obiekt w stercie, ale [] może ponownie użyć komórki pamięci z wielu powodów.
istnieje jedna różnica w zachowaniu między [] i list (), jak pokazuje poniższy przykład. musimy użyć list (), jeśli chcemy zwrócić listę liczb, w przeciwnym razie otrzymamy obiekt mapy! Nie wiem jednak, jak to wyjaśnić.
sth = [(1,2), (3,4),(5,6)]
sth2 = map(lambda x: x[1], sth)
print(sth2) # print returns object <map object at 0x000001AB34C1D9B0>
sth2 = [map(lambda x: x[1], sth)]
print(sth2) # print returns object <map object at 0x000001AB34C1D9B0>
type(sth2) # list
type(sth2[0]) # map
sth2 = list(map(lambda x: x[1], sth))
print(sth2) #[2, 4, 6]
type(sth2) # list
type(sth2[0]) # int
Para nawiasów prostokątnych oznacza jeden z obiektów listy lub indeks indeksu, my_List [x].
Para nawiasów klamrowych oznacza obiekt słownika.
a_list = ['on', 'off', 1, 2]
a_dict = {on: 1, off: 2}
W większości przypadków jest to kwestia wyboru. To kwestia preferencji.
Pamiętaj jednak, że jeśli masz na przykład klawisze numeryczne, nie możesz tego zrobić:
mydict = dict(1="foo", 2="bar")
Musisz zrobić:
mydict = {"1":"foo", "2":"bar"}
mydict = {1:"foo", 2:"bar"}
(bez cudzysłowów dla kluczy).
list(i for i in range(10) if i % 2)