2012-04-18 31 views
5

Pracując nad problemem z klasy Google Python, sformułowałem następujący wynik 2-3 za pomocą przykładów ze stosu overflow-sortowania listę krotek w Pythonie

def sort_last(tuples): 
    return [b for a,b in sorted((tup[1], tup) for tup in tuples)] 

print sort_last([(1, 3), (3, 2), (2, 1)]) 

dowiedziałem listowych wczoraj, więc wiedzieć trochę o zrozumieniu listy, ale jestem zdezorientowany, jak to rozwiązanie działa ogólnie. Pomóż mi to zrozumieć (druga linia w funkcji).

+0

można dodać link do "klasy Google Pythona? – xtian

+0

https://developers.google.com/edu/python/?csw=1 – Varun

Odpowiedz

6

Ten wzór nazywa się dekorowanie-sortowanie-nieurodzaj.

  1. włączyć każdy (1, 3) w (3, (1, 3)), owijając każdą tuple w nowej krotki, z pozycji, którą chcesz sortować według pierwszego.
  2. Sortujesz, z zewnętrznym tuple, upewniając się, że drugi element w oryginalnym tuple jest posortowany jako pierwszy.
  3. Powracasz z (3, (1, 3)) do (1, 3), zachowując kolejność na liście.

W Pythonie jawne dekorowanie jest prawie zawsze niepotrzebne. Zamiast tego należy użyć key argument of sorted:

sorted(list_of_tuples, key=lambda tup: tup[1]) # or key=operator.itemgetter(1) 

Albo, jeśli chcesz, aby posortować w odwróconej wersji tuple, bez względu na jego długość:

sorted(list_of_tuples, key=lambda tup: tup[::-1]) 
           # or key=operator.itemgetter(slice(None, None, -1)) 
+0

Wielkie dzięki, teraz jest jasne, czy możesz mi powiedzieć coś na temat lambda (wiem, że mogę znaleźć o tym na stosie przelewów, ale chcę wiedzieć o używaniu tutaj lambdy) – Varun

+2

@Varun 'lambda' pozwala ci tylko deklaruj funkcję wewnątrz wyrażenia. Jest to to samo co 'def first_item (tup): return tup [1]' poza wywołaniem funkcji, następnie 'key = first_item' w wywołaniu funkcji. Zobacz [Lambda Forms] (http://docs.python.org/tutorial/controlflow.html#lambda-forms) w samouczku Python. – agf

+0

"Ten wzór nazywa się dekoracją-sortuj-nieśmiertelny" .. nigdy nie wiedziałem, że ma imię – Abhijit

2

Twój przykład działa poprzez utworzenie nowej listy z elementem o indeksie 1, po której następuje oryginalna krotka dla każdej krotki na liście. Na przykład. (3,(1,3)) dla pierwszego elementu. Posortowana funkcja sortuje według każdego elementu, zaczynając od indeksu 0, aby lista została posortowana według drugiego elementu. Funkcja przechodzi następnie przez każdy element na nowej liście i zwraca krotki orignal.

Innym sposobem wykonania tej czynności jest użycie parametru key w posortowanej funkcji sortującej w oparciu o wartość key. W takim przypadku chcesz, aby element key był elementem każdej krotki o indeksie 1.

>>> from operator import itemgetter 
>>> sorted([(1, 3), (3, 2), (2, 1)],key=itemgetter(1)) 
+0

Powoduje on _nie_ odwrócenie każdej krotki na liście. Zawija każdą krotkę w kolejną krotkę. – agf

+0

No dobra, tęskniłem za tym, myślałem, że to tup [1], tup [0], ale teraz, gdy spojrzałem na to, widziałem, że źle odczytałem, będę edytować moją odpowiedź. – jamylak

3

Umożliwia rozbicie go:

W : [(tup[1],tup) for tup in tuples]

Out: [(3, (1, 3)), (2, (3, 2)), (1, (2, 1))]

Po prostu stworzyliśmy nową krotkę, w której jej pierwsza wartość jest ostatnią wartością wewnętrznej krotki - w ten sposób jest sortowana według drugiej wartości każdej krotki w "krotkach".

Teraz sortować wracającą listę:

w: sorted([(3, (1, 3)), (2, (3, 2)), (1, (2, 1))])

Out: [(1, (2, 1)), (2, (3, 2)), (3, (1, 3))]

Więc mamy teraz nasza lista posortowana według jego 2nd wartości każdej krotki. Pozostaje tylko wyodrębnić oryginalną krotkę, a robi się to przez wykonanie b tylko z pętli for.

Zrozumienie listy iteruje daną listę (sorted([...] w tym przypadku) i zwraca wyodrębnione wartości według zamówienia.

+0

Wielkie dzięki, ładnie wyjaśnione. – Varun

0

Pls odnoszą się do przyjętej odpowiedź .. + to jest przykład dla lepszej wizualizacji,

key to funkcja, która zostanie wywołana, aby przekształcić elementy kolekcji dla porównania .. jak compareTo metody w Javie.

Parametr przekazywany do klucza musi być czymś, co można wywołać. W tym przypadku użycie lambda tworzy anonimową funkcję (która jest wywoływalna).
Składnia lambda to słowo lambda poprzedzające nazwę iterowalną, a następnie pojedynczy blok kodu.

Poniżej przykład sortujemy listę krotek, która zawiera informacje o określonym czasie zdarzenia i nazwy aktora.

Sortujemy tę listę według czasu wystąpienia zdarzenia - który jest 0 elementem krotki.

Krzyczeć dla Ready Playera Fani! =)

>>> gunters = [('2044-04-05', 'parzival'), ('2044-04-07', 'aech'), ('2044-04-06', 'art3mis')] 
>>> gunters.sort(key=lambda tup: tup[0]) 
>>> print gunters 
[('2044-04-05', 'parzival'), ('2044-04-06', 'art3mis'), ('2044-04-07', 'aech')] 

Uwaga - s.sort([cmp[, key[, reverse]]]) sortuje elementy s w miejscu