2015-03-19 18 views
13

Używam listę p = [[1,2,3],[4,5,6]]Różnica między zamkiem (lista) i zamek (* lista)

Jeśli zrobić:

>>>d=zip(p) 
>>>list(d) 
[([1, 2, 3],), ([4, 5, 6],)] 

Choć, co faktycznie chcę uzyskuje się, stosując w ten sposób:

>>>d=zip(*p) 
>>>list(d) 
[(1, 4), (2, 5), (3, 6)] 

Dowiedziałem się, że dodanie "*" przed nazwą listy daje wymagane wyniki, ale nie widzę różnicy w ich działaniu. Czy możesz wyjaśnić różnicę?

Odpowiedz

1

Chociaż nie jest to odpowiedź na zadane pytanie, powinna pomóc. Ponieważ zip jest używany do łączenia dwóch list, powinieneś zrobić coś takiego: list(zip(p[0], p[1])), aby osiągnąć to, czego oczekujesz.

23

zip chce mieć kilka argumentów do skompresowania, ale to, co masz, to pojedynczy argument (lista, której elementami są również listy). * w wywołaniu funkcji "rozpakowuje" listę (lub inną iterację), czyniąc każdy z jej elementów osobnym argumentem. Więc bez *, robisz zip([[1,2,3],[4,5,6]]). Dzięki * robisz zip([1,2,3], [4,5,6]).

0

W skrócie, z x = [1,2,3], podczas wywoływania f(x), x otrzymuje 1 argument [1, 2, 3]. Gdy używasz operatora gwiazdki f(*x), f otrzymuje trzy argumenty, jest to odpowiednik wywołania f(1,2,3).

Dlatego w dokumentacji Pythona często można zobaczyć some_function(*args, **kwargs). Tutaj operator podwójnej gwiazdy robi to samo, ale dla słownika: z d={"some_arg":2, "some_other_arg":3}, wywołanie f(**d) jest takie samo jak f(some_arg=2, some_other_arg=3).

Teraz, gdy używasz zip, efektywnie chcesz zip [1,2,3] z [4,5,6], więc chcesz przekazać 2 args do zip, dlatego potrzebujesz operatora gwiazdy. Bez tego przekazujesz tylko jeden argument.

+1

Definicja funkcji * z '*' lub '**' jak to, o czym wspomniałeś, jest innym zastosowaniem operatora '*'. W tym kontekście służy do tworzenia [funkcji variadycznych] (http://en.wikipedia.org/wiki/Variadic_function). Są one związane z '*', o którym mówi OP, który bardziej przypomina cukier syntaktyczny dla operatora 'apply'. To zły pomysł, aby pomylić oba. –

+0

Twierdzę, że są one dwoma aspektami tej samej koncepcji (chociaż różne zachowania). W jednym przypadku (definicja funkcji) określasz, że funkcja zaakceptuje kilka argumentów zgrupowanych pod jedną nazwą (args), podczas gdy w drugiej wysyłasz jedną nazwę do kilku argumentów. Są więc oczywiście różne, ale są ściśle połączone ze sobą pojęciami składniowymi, a zrozumienie sprawia, że ​​rozumiesz drugie. – vermillon

+0

Tak jak powiedziałem, są spokrewnione, ale biorąc pod uwagę brak wiedzy specjalistycznej w tej dziedzinie, będzie to bardziej mylące niż pouczające. –

1

Właściwie * rozpakowuje operatora, jak i funkcji zip zaakceptować listę iterable można przekazać wiele iterable do tej funkcji:

więc wynikiem *p jest:

[1,2,3],[4,5,6] 

i zip(*p) jest równy zip([1,2,3],[4,5,6]).

także dla lepszego zrozumienia, że ​​* notatki mogą być używane do rozpakowania listę:

>>> zip(*zip(*p)) 
[(1, 2, 3), (4, 5, 6)] 

Powyższe polecenie rozpakowania wynik zip(*p) więc musisz:

zip((1, 4), (2, 5), (3, 6)) 

zip([iterable, ...])

Ta funkcja zwraca listę krotek, gdzie i-ta krotka zawiera i-ty element z każdej z sekwencji argumentów lub iterables. Zwrócona lista jest skrócona do długości najkrótszej sekwencji argumentów.Gdy istnieje wiele argumentów, które są tej samej długości, zip() jest podobny do map() z początkowym argumentem None. Za pomocą argumentu pojedynczej sekwencji zwraca listę 1-krotnych. Bez argumentów zwraca pustą listę.

3

Operator * rozpakowuje argumenty w instrukcji wywołania funkcji.

Rozważmy

def add(x, y): 
    return x + y 

jeśli masz listę t = [1,2], można powiedzieć add(t[0], t[1]) który niepotrzebnie gadatliwy czy można „rozpakować” t na oddzielne argumenty za pomocą operatora * jak tak add(*t).

Oto, co dzieje się w twoim przykładzie. zip(p) jest jak uruchamianie zip([[1,2,3],[4,5,6]]). Zip ma tutaj jeden argument, więc po prostu zwraca go jako krotkę.

zip(*p) jest jak uruchamianie zip([1,2,3], [4,5,6]). Jest to podobne do działania zip(p[0], p[1]), a otrzymasz oczekiwany wynik.

0

Operator "*" unpacks wyświetla listę i stosuje ją do funkcji. Funkcja zip wykonuje listy n i tworzy pary n krotki każdego elementu z obu listach:

suwak ([iterowalny, ...])

Funkcja ta zwraca listę krotki, gdzie I -ta krotka zawiera i-ty element z każdej z sekwencji argumentów lub iterables. Zwrócona lista jest skrócona do długości najkrótszej sekwencji argumentów . Gdy istnieje wiele argumentów, które są wszystkie z tej samej długości, zip() jest podobne do mapy() z początkowym argumentem Brak. Za pomocą argumentu pojedynczej sekwencji zwraca listę 1-krotnych. Bez argumentów zwraca pustą listę.

Zasadniczo, za pomocą * z [[1,2,3],[4,5,6]], jesteś przejazdem [1,2,3] i [4,5,6] jako argumenty zip.