Odpowiedzi:
sorted()
zwraca nową posortowaną listę, pozostawiając nienaruszoną oryginalną listę. list.sort()
sortuje listę w miejscu , mutując indeksy listy i zwraca None
(jak wszystkie operacje w miejscu).
sorted()
działa na dowolnych iterowalnych, nie tylko listach. Ciągi, krotki, słowniki (dostaniesz klucze), generatory itp., Zwracając listę zawierającą wszystkie posortowane elementy.
Użyj, list.sort()
jeśli chcesz zmutować listę, sorted()
gdy chcesz ponownie posortować nowy obiekt. Zastosowanie sorted()
gdy chcemy uporządkować coś, co jest iterable, a nie lista jeszcze .
W przypadku list list.sort()
jest szybszy niż sorted()
dlatego, że nie musi tworzyć kopii. W przypadku innych iteracji nie masz wyboru.
Nie, nie możesz odzyskać oryginalnych pozycji. Po zadzwonieniu list.sort()
oryginalne zamówienie zniknęło.
None
, jest to znak, że operacje są wykonywane w miejscu, dlatego kiedy chcesz wydrukować list.sort()
, zwraca None.
Jaka jest różnica między
sorted(list)
vslist.sort()
?
list.sort
mutuje listę w miejscu i zwraca None
sorted
przyjmuje dowolną iterowalną i zwraca posortowaną nową listę.sorted
jest równoważne z tą implementacją Pythona, ale wbudowana funkcja CPython powinna działać wymiernie szybciej, ponieważ jest napisana w C:
def sorted(iterable, key=None):
new_list = list(iterable) # make a new list
new_list.sort(key=key) # sort it
return new_list # return it
kiedy użyć którego?
list.sort
gdy nie chcesz zachować oryginalnej kolejności sortowania (dzięki temu będziesz mógł ponownie użyć listy w miejscu) i gdy jesteś jedynym właścicielem listy (jeśli lista jest współdzielona przez inny kod, a ty mutuj go, możesz wprowadzić błędy, w których używana jest ta lista).sorted
gdy chcesz zachować oryginalną kolejność sortowania lub gdy chcesz utworzyć nową listę, do której należy tylko kod lokalny.Czy oryginalne pozycje listy można pobrać po list.sort ()?
Nie - chyba że sam wykonałeś kopię, informacje te zostaną utracone, ponieważ sortowanie odbywa się na miejscu.
„A który jest szybszy? A o ile szybszy?”
Aby zilustrować karę tworzenia nowej listy, użyj modułu timeit, oto nasza konfiguracja:
import timeit
setup = """
import random
lists = [list(range(10000)) for _ in range(1000)] # list of lists
for l in lists:
random.shuffle(l) # shuffle each list
shuffled_iter = iter(lists) # wrap as iterator so next() yields one at a time
"""
A oto nasze wyniki dla listy losowo ułożonych 10000 liczb całkowitych, jak widzimy tutaj, obaliliśmy starszy mit dotyczący kosztów tworzenia listy :
Python 2.7
>>> timeit.repeat("next(shuffled_iter).sort()", setup=setup, number = 1000)
[3.75168503401801, 3.7473005310166627, 3.753129180986434]
>>> timeit.repeat("sorted(next(shuffled_iter))", setup=setup, number = 1000)
[3.702025591977872, 3.709248117986135, 3.71071034099441]
Python 3
>>> timeit.repeat("next(shuffled_iter).sort()", setup=setup, number = 1000)
[2.797430992126465, 2.796825885772705, 2.7744789123535156]
>>> timeit.repeat("sorted(next(shuffled_iter))", setup=setup, number = 1000)
[2.675589084625244, 2.8019039630889893, 2.849375009536743]
Po kilku opiniach zdecydowałem, że pożądany będzie kolejny test o różnych cechach. Tutaj podaję tę samą losowo uporządkowaną listę o długości 100 000 dla każdej iteracji 1000 razy.
import timeit
setup = """
import random
random.seed(0)
lst = list(range(100000))
random.shuffle(lst)
"""
Interpretuję różnicę tego większego rodzaju pochodzącą z kopiowania wspomnianego przez Martijna, ale nie dominuje ona do punktu podanego w starszej, bardziej popularnej odpowiedzi tutaj, tutaj wzrost czasu wynosi tylko około 10%
>>> timeit.repeat("lst[:].sort()", setup=setup, number = 10000)
[572.919036605, 573.1384446719999, 568.5923951]
>>> timeit.repeat("sorted(lst[:])", setup=setup, number = 10000)
[647.0584738299999, 653.4040515829997, 657.9457361929999]
Uruchomiłem również powyższe na znacznie mniejszym formacie i zobaczyłem, że nowa sorted
wersja kopii nadal zajmuje około 2% dłuższy czas działania na długości 1000.
Poke również uruchomił swój własny kod, oto kod:
setup = '''
import random
random.seed(12122353453462456)
lst = list(range({length}))
random.shuffle(lst)
lists = [lst[:] for _ in range({repeats})]
it = iter(lists)
'''
t1 = 'l = next(it); l.sort()'
t2 = 'l = next(it); sorted(l)'
length = 10 ** 7
repeats = 10 ** 2
print(length, repeats)
for t in t1, t2:
print(t)
print(timeit(t, setup=setup.format(length=length, repeats=repeats), number=repeats))
Znalazł dla sortowania według długości 1000000, (uruchomił 100 razy) podobny wynik, ale tylko o około 5% wzrost w czasie, oto wynik:
10000000 100
l = next(it); l.sort()
610.5015971539542
l = next(it); sorted(l)
646.7786222379655
Duża lista sortowana przy sorted
tworzeniu kopii prawdopodobnie zdominuje różnice, ale samo sortowanie zdominuje operację, a uporządkowanie kodu wokół tych różnic byłoby przedwczesną optymalizacją. Użyłbym, sorted
gdy potrzebuję nowej posortowanej listy danych, i użyłbym, list.sort
gdy potrzebowałem posortować listę w miejscu, i pozwolić mi określić moje wykorzystanie.
sorted()
należy przydzielić nowy obiekt listy i skopiować odniesienia; reszta ścieżek kodu jest identyczna. Sprawdź, czy możesz uruchomić te same testy z większymi listami. Porównaj to z tworzeniem kopii list i sprawdź, czy możesz odtworzyć znalezione różnice itp.
Główną różnicą jest to, że sorted(some_list)
zwraca nowylist
:
a = [3, 2, 1]
print sorted(a) # new list
print a # is not modified
i some_list.sort()
, sortuje listę w lokalu :
a = [3, 2, 1]
print a.sort() # in place
print a # it's modified
Pamiętaj, że ponieważ a.sort()
nic nie zwraca, print a.sort()
zostanie wydrukowane None
.
Czy po list.sort () można pobrać oryginalne pozycje listy?
Nie, ponieważ modyfikuje oryginalną listę.
print a.sort()
nic nie wydrukuje.
None
, wyjaśnię to.
Funkcja .sort () przechowuje wartość nowej listy bezpośrednio w zmiennej listy; więc odpowiedź na twoje trzecie pytanie brzmiałaby NIE. Również jeśli zrobisz to za pomocą sortowania (listy), możesz go użyć, ponieważ nie jest przechowywany w zmiennej listy. Czasami również metoda .sort () działa jako funkcja lub mówi, że pobiera w niej argumenty.
Musisz przechowywać wartość posortowanej (listy) w zmiennej jawnie.
Również w przypadku krótkiego przetwarzania danych prędkość nie będzie różnicy; ale dla długich list; powinieneś bezpośrednio użyć metody .sort () do szybkiej pracy; ale znów staniecie wobec nieodwracalnych działań.
list.sort()
Metoda sortuje przedmiot listy na miejscu.
.sort()
metoda pobiera argument i działa jako funkcja. Nazywamy to również metodą, ponieważ jest to atrybut typu danych listy.
Oto kilka prostych przykładów, które pokazują różnicę w działaniu:
Zobacz listę liczb tutaj:
nums = [1, 9, -3, 4, 8, 5, 7, 14]
Dzwoniąc sorted
na tę listę, sorted
zrobi kopię listy. (Oznacza to, że Twoja oryginalna lista pozostanie niezmieniona).
Zobaczmy.
sorted(nums)
zwroty
[-3, 1, 4, 5, 7, 8, 9, 14]
Patrząc nums
ponownie
nums
Widzimy oryginalną listę (niezmienioną i NIE posortowaną). sorted
nie zmienił oryginalnej listy
[1, 2, -3, 4, 8, 5, 7, 14]
Biorąc tę samą nums
listę i stosując na niej sort
funkcję, zmieni aktualną listę.
Zobaczmy.
Począwszy od naszej nums
listy, aby upewnić się, treść jest nadal taka sama.
nums
[-3, 1, 4, 5, 7, 8, 9, 14]
nums.sort()
Teraz oryginalna lista liczb jest zmieniona i patrząc na liczby widzimy, że nasza oryginalna lista uległa zmianie i jest teraz posortowana.
nums
[-3, 1, 2, 4, 5, 7, 8, 14]
Uwaga: Najprostsza różnica między sort () a sorted () to: sort () nie zwraca żadnej wartości, podczas gdy sorted () zwraca listę iterowalną.
sort () nie zwraca żadnej wartości.
Metoda sort () po prostu sortuje elementy danej listy w określonej kolejności - Rosnąco lub Malejąco bez zwracania żadnej wartości.
Składnia metody sort () to:
list.sort(key=..., reverse=...)
Alternatywnie można również użyć wbudowanej funkcji Pythona sorted () w tym samym celu. posortowana funkcja zwraca posortowaną listę
list=sorted(list, key=..., reverse=...)
sorted()
argument ciągu, ale uważasz, że to lista, otrzymasz wynik listy, a nie ciąg : niesorted("abcd", reverse=True)
daje['d', 'c', 'b', 'a']
"dcba"