Jaka jest różnica między listą sortowaną a listą.sort ()`?

list.sort() sortuje listę i zapisuje posortowaną listę, podczas gdy sorted(list) zwraca posortowaną kopię listy, bez zmiany oryginalnej listy.

  • Ale kiedy użyć którego?
  • A który jest szybszy? O ile szybciej?
  • czy można odzyskać oryginalne pozycje listy po list.sort()?
Author: smci, 2014-03-17

4 answers

sorted() zwraca nową posortowaną listę, pozostawiając oryginalną listę bez zmian. list.sort() sortuje listę in-place , mutując indeksy listy i zwraca None (Jak wszystkie operacje in-place).

sorted() działa na dowolnych iterowalnych, nie tylko listach. Ciągi, krotki, słowniki( dostaniesz klucze), Generatory itp., zwracanie listy zawierającej wszystkie elementy, posortowane.

  • Użyj list.sort(), gdy chcesz zmutować listę, sorted(), gdy chcesz, aby nowa posortowana Cofnij obiekt. Użyj sorted(), gdy chcesz posortować coś, co jest iterowalne, a nie lista Jeszcze .

  • W przypadku List, list.sort() jest szybszy niż sorted(), ponieważ nie musi tworzyć kopii. Dla innych iterable, nie masz wyboru.

  • Nie, Nie można odzyskać oryginalnych pozycji. Po wywołaniu list.sort() oryginalna kolejność przepadła.

 187
Author: Martijn Pieters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-25 08:34:54

Jaka jest różnica między sorted(list) a list.sort()?

  • list.sort mutuje listę w miejscu i zwraca None
  • sorted pobiera dowolną iterowalną i zwraca nową listę, posortowaną.

sorted jest odpowiednikiem tej implementacji Pythona, ale wbudowana funkcja CPython powinna działać znacznie szybciej, ponieważ jest napisana w języku 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?

  • Użyj list.sort, gdy nie chcesz zachować oryginału kolejność sortowania (W ten sposób będziesz mógł ponownie użyć listy na miejscu w pamięci.) i kiedy jesteś jedynym właścicielem listy (jeśli lista jest współdzielona przez inny kod a jeśli go zmutujesz, możesz wprowadzić błędy tam, gdzie ta lista jest używana.)
  • użyj sorted, gdy chcesz zachować oryginalną kolejność sortowania lub gdy chcesz utworzyć nową listę, której właścicielem jest tylko twój kod lokalny.

Czy oryginalne pozycje listy mogą być pobierane po liście.Sortuj ()?

Nie-chyba że ty zrobiłem kopię siebie, że informacje są utracone, ponieważ sortowanie odbywa się na miejscu.

"a który jest szybszy? O ile szybciej?"

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 widać tutaj, obaliliśmy starszy mit o kosztach 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 inny test będzie pożądany z innymi cechami. 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ę tę większą różnicę sortowania wynikają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]

Prowadziłem również powyżej na znacznie mniejszym sortowaniu i zobaczyłem, że nowa wersja sorted nadal zajmuje około 2% dłuższy czas pracy na rodzaju 1000 długości.

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))
W 2007 roku, po raz pierwszy w historii, w Polsce, w 2008 roku, w Polsce, w 2009 roku, w Polsce, w 2009 roku, w Polsce, w 2009 roku, w Polsce, w 2009 roku, w Polsce, w 2009 roku, w Polsce, w 2009 roku, w Polsce, w 2009 roku, w 2009 roku.]}
10000000 100
l = next(it); l.sort()
610.5015971539542
l = next(it); sorted(l)
646.7786222379655

Wniosek:

Duża lista sortowana za pomocą sorted robienie kopii prawdopodobnie zdominuje różnice, ale sortowanie sama operacja dominuje, a organizowanie kodu wokół tych różnic byłoby przedwczesną optymalizacją. Używam sorted, gdy potrzebuję nowej posortowanej listy danych, i używam list.sort, gdy muszę posortować listę na miejscu, i niech to determinuje moje użycie.

 26
Author: Aaron Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 21:20:53

Główna różnica polega na tym, że sorted(some_list) zwraca Nowy list:

a = [3, 2, 1]
print sorted(a) # new list
print a         # is not modified

I some_list.sort(), sortuje listę w miejscu:

a = [3, 2, 1]
print a.sort() # in place
print a         # it's modified

Zauważ że ponieważ a.sort() niczego nie zwraca, print a.sort() wydrukuje None.


Czy lista oryginalnych pozycji może być pobrana po liście.Sortuj ()?

Nie, ponieważ modyfikuje oryginalną listę.

 7
Author: Christian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-16 20:19:46

The .funkcja sort() przechowuje wartość nowej listy bezpośrednio w zmiennej list; więc odpowiedź na twoje trzecie pytanie będzie brzmiała nie. Również jeśli zrobisz to używając sorted( list), wtedy możesz go użyć, ponieważ nie jest przechowywany w zmiennej list. Czasami też .metoda sort() działa jako funkcja lub mówi, że pobiera w niej argumenty.

Musisz jawnie przechowywać wartość sorted(list) w zmiennej.

Również w przypadku krótkiego przetwarzania danych prędkość nie będzie miała różnicy; ale dla długie listy; należy użyć bezpośrednio .metoda sort() do szybkiej pracy; ale znowu czeka cię nieodwracalne działanie.

 1
Author: Vicrobot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-01 14:53:48