Nie byłem w stanie znaleźć zrozumiałego wyjaśnienia, jak właściwie korzystać z itertools.groupby()
funkcji Pythona . To, co próbuję zrobić, to:
- Zrób listę - w tym przypadku dzieci zobiektywizowanego
lxml
elementu - Podziel go na grupy na podstawie niektórych kryteriów
- Później iteruj osobno po każdej z tych grup.
Przejrzałem dokumentację i przykłady , ale miałem problemy z zastosowaniem ich poza prostą listą liczb.
Jak więc korzystać z itertools.groupby()
? Czy jest inna technika, której powinienem użyć? Docenione zostaną również wskaźniki dobrego „wstępnego” czytania.
Odpowiedzi:
WAŻNA UWAGA: Najpierw musisz posortować dane .
To, czego nie dostałem, to to, że w przykładowej konstrukcji
k
jest bieżącym kluczem grupowania ig
jest iteratorem, którego można użyć do iteracji w grupie zdefiniowanej przez ten klucz grupowania. Innymi słowy,groupby
sam iterator zwraca iteratory.Oto przykład tego, używając jaśniejszych nazw zmiennych:
To da ci wynik:
W tym przykładzie
things
jest to lista krotek, w której pierwszy element w każdej krotce jest grupą, do której należy drugi element.groupby()
Funkcja ma dwa parametry: (1) dane do grupy lub (2) funkcji do grupy, do której za pomocą.lambda x: x[0]
Mówi tutaj,groupby()
aby użyć pierwszego elementu w każdej krotce jako klucza grupowania.W powyższej
for
instrukcjigroupby
zwraca trzy pary (klucz, iterator grupy) - raz dla każdego unikalnego klucza. Za pomocą zwróconego iteratora można iterować poszczególne elementy w tej grupie.Oto nieco inny przykład z tymi samymi danymi, wykorzystujący rozumienie listy:
To da ci wynik:
źródło
groupby(sorted(my_collection, key=lambda x: x[0]), lambda x: x[0]))
założyć, żemy_collection = [("animal", "bear"), ("plant", "cactus"), ("animal", "duck")]
i chcesz pogrupować wedługanimal or plant
Przykład w dokumentacji Pythona jest dość prosty:
Tak więc w twoim przypadku dane są listą węzłów,
keyfunc
gdzie logika funkcji kryteriów idzie, a następniegroupby()
grupuje dane.Zanim zadzwonisz, musisz uważnie posortować dane według kryteriów,
groupby
aby nie zadziałały.groupby
Metoda faktycznie po prostu dokonuje iteracji listy i za każdym razem, gdy zmienia się klucz, tworzy nową grupę.źródło
keyfunc
i powiedziałeś: „tak, wiem dokładnie, co to jest, ponieważ ta dokumentacja jest dość prosta.”? Niesamowite!itertools.groupby
to narzędzie do grupowania elementów.Z dokumentów , zbieramy dalej, co może zrobić:
groupby
obiekty dają pary klucz-grupa, gdzie grupa jest generatorem.funkcje
Porównania
Używa
Uwaga: Kilka ostatnich przykładów pochodzi z PyCon Víctora Terróna (dyskusja) (hiszpański) , „Kung Fu at Dawn with Itertools”. Zobacz także
groupby
kod źródłowy napisany w C.* Funkcja, w której wszystkie elementy są przekazywane i porównywane, wpływając na wynik. Inne obiekty z kluczowymi funkcjami obejmują
sorted()
,max()
imin()
.Odpowiedź
źródło
[''.join(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
.list()
,tuple()
) lub używane w pętli / zrozumieniu, aby wyświetlić zawartość. Są to zwolnienia, które autor prawdopodobnie wykluczył w celu zaoszczędzenia miejsca.Sztuczka neato z Groupby polega na uruchomieniu kodowania długości w jednym wierszu:
da ci listę 2-krotek, w których pierwszy element to znak, a drugi to liczba powtórzeń.
Edycja: Zauważ, że właśnie to się oddziela
itertools.groupby
odGROUP BY
semantyki SQL : itertools nie sortuje iteratora z góry, a więc grupy z tym samym „kluczem” nie są scalane.źródło
Inny przykład:
prowadzi do
Zauważ, że igroup jest iteratorem (iteratorem, jak to nazywa dokumentacja).
Jest to przydatne do dzielenia generatora:
Kolejny przykład grupowania - gdy klucze nie są posortowane. W poniższym przykładzie elementy w xx są pogrupowane według wartości w yy. W takim przypadku najpierw wyprowadzany jest jeden zestaw zer, a następnie zestaw zer, a następnie ponownie zestaw zer.
Produkuje:
źródło
OSTRZEŻENIE:
Lista składni (groupby (...)) nie będzie działać w zamierzony sposób. Wydaje się, że niszczy wewnętrzne obiekty iteratora, więc używa
będzie produkować:
Zamiast listy (groupby (...)) spróbuj [(k, list (g)) dla k, g w groupby (...)] lub jeśli często używasz tej składni,
i uzyskaj dostęp do funkcji grupowania, unikając jednocześnie tych irytujących (dla małych danych) iteratorów.
źródło
Chciałbym podać inny przykład, w którym funkcja grupowania bez sortowania nie działa. Na podstawie przykładu Jamesa Sulaka
wyjście jest
są dwie grupy z pojazdem, podczas gdy można oczekiwać tylko jednej grupy
źródło
@CaptSolo, próbowałem twojego przykładu, ale to nie zadziałało.
Wynik:
Jak widać, są dwa o i dwa e, ale podzielili się na osobne grupy. Wtedy zdałem sobie sprawę, że musisz posortować listę przekazaną do funkcji grupowania. Prawidłowe użycie to:
Wynik:
Wystarczy pamiętać, że jeśli lista nie zostanie posortowana, funkcja grupowania nie będzie działać !
źródło
źródło
Możesz użyć groupby, aby pogrupować rzeczy do iteracji. Dajesz grupie opcję iterowalną oraz opcjonalną funkcję kluczową / wywoływalną, za pomocą której można sprawdzać elementy wychodzące z iterowalnej, i zwraca iterator, który daje dwukrotność wyniku kluczowego wywołania i rzeczywistych pozycji w kolejna iterowalna. Z pomocy:
Oto przykład grupowania za pomocą coroutine w celu grupowania według liczby, używa klucza wywoływalnego (w tym przypadku
coroutine.send
), aby po prostu wyliczyć liczbę dla dowolnej liczby iteracji i zgrupowanego pod-iteratora elementów:odciski
źródło
Pomocny może być jeden przydatny przykład:
Przykładowe dane wejściowe: 14445221
Wyjściowa próbka: (1,1) (3,4) (1,5) (2,2) (1,1)
źródło
Ta podstawowa implementacja pomogła mi zrozumieć tę funkcję. Mam nadzieję, że pomaga to również innym:
źródło
Możesz napisać własną funkcję grupowania:
źródło