Tworzenie pustej listy w Pythonie

243

Jaki jest najlepszy sposób na utworzenie nowej pustej listy w Pythonie?

l = [] 

lub

l = list()

Proszę o to z dwóch powodów:

  1. Przyczyny techniczne, które są szybsze. (utworzenie klasy powoduje narzut?)
  2. Czytelność kodu - która jest standardową konwencją.
użytkownik225312
źródło
4
"szybciej"? Dlaczego nie uciekłeś?
S.Lott,

Odpowiedzi:

335

Oto, w jaki sposób możesz przetestować, który fragment kodu jest szybszy:

% python -mtimeit  "l=[]"
10000000 loops, best of 3: 0.0711 usec per loop

% python -mtimeit  "l=list()"
1000000 loops, best of 3: 0.297 usec per loop

Jednak w praktyce ta inicjalizacja jest najprawdopodobniej bardzo małą częścią twojego programu, więc martwienie się tym jest prawdopodobnie błędne.

Czytelność jest bardzo subiektywna. Wolę [], ale niektórzy bardzo dobrze znani ludzie, jak Alex Martelli, wolą, list()ponieważ można to wymówić .

unutbu
źródło
12
Wow, dzięki za profilowanie. Zawsze chciałem wiedzieć, jak to się stało.
user225312
Dlaczego list('')daje []zamiast ['']?
Chris_Rands,
Wynika to z faktu, że ta funkcja tworzy listę typów iterowalnych, dlatego nie można wstawić więcej niż jednego argumentu. (Spróbuj wpisać list('abcd')i zrozumiesz wszystko)
Ivan Lavrenov
133

list()jest z natury wolniejszy niż [], ponieważ

  1. istnieje wyszukiwanie symboli (nie ma możliwości, aby python wiedział z góry, jeśli nie zdefiniowałeś na nowo listy, aby była czymś innym!),

  2. istnieje wywołanie funkcji,

  3. następnie musi sprawdzić, czy został przekazany iterowalny argument (aby mógł utworzyć listę z jego elementami) ps. w naszym przypadku nie ma żadnego, ale istnieje opcja „jeśli”

W większości przypadków różnica prędkości nie robi jednak żadnej praktycznej różnicy.

Nas Banov
źródło
38
+1: Dobrze jest zrozumieć, dlaczego list()jest wolniejszy niż []!
Eric O Lebigot,
2
W takim przypadku list()musi tylko sprawdzić, czy w ogóle jest jakiś argument ... „sprawdź, czy iterowalny” i „utwórz listę z elementami” po prostu się nie zdarza; mają zastosowanie tylko wtedy, gdy występuje argument. Możliwe jest nawet, że kod C []wywołuje ten sam kod C co list(). W każdym razie czas związany z (c) byłby niewielki w porównaniu z (a) + (b).
John Machin
1
@John Machin - przepraszam za zamieszanie, co miałem na myśli w (c) to, że trzeba będzie sprawdzić, czy nie było argumentu, tak. reszta dotyczyła tego, co się stanie, jeśli pojawią się kłótnie, których w naszym przypadku nie ma
Nas Banov
16

Używam [].

  1. Jest to szybsze, ponieważ notacja listy jest zwarciem.
  2. Tworzenie listy z elementami powinno wyglądać mniej więcej tak samo, jak tworzenie listy bez, dlaczego powinna istnieć różnica?
Georg Schölly
źródło
3

Tak naprawdę nie wiem o tym, ale z doświadczenia wydaje mi się, że jpcgt ma rację. Poniższy przykład: jeśli użyję następującego kodu

t = [] # implicit instantiation
t = t.append(1)

w tłumaczu wywoływanie t daje mi po prostu „t” bez żadnej listy, a jeśli dołączę coś innego, np

t = t.append(2)

Pojawia się błąd „Obiekt NoneType” nie ma atrybutu „append”. Jeśli jednak tworzę listę przez

t = list() # explicit instantiation

to działa dobrze.

Yinyue
źródło
15
To dlatego, że t.append(1)modyfikuje tw miejscu, to nie zwraca niczego, ale Nonei jesteś przypisywanie tego Nonecelu t. Więc tteraz odnosi się do Nonezamiast do listy. Twoim błędem było pisanie t=t.append(1)zamiast po prostu t.append(1). Zauważysz to samo zachowanie list(), więc nie ma tutaj różnicy.
Darkonaut,
1

Wystarczy podkreślić odpowiedź @Darkonaut, ponieważ uważam, że powinna być bardziej widoczna.

new_list = []lub new_list = list()oba są w porządku (ignorowanie wydajności), ale append()zwraca None, w wyniku czego nie możesz tego zrobić new_list = new_list.append(something.

Jestem bardzo zaskoczony taką decyzją typu powrotu. Fuj

oVo
źródło