`Sorted (list)` vs `list.sort ()` arasındaki fark nedir?


194

list.sort()listeyi sıralar ve orijinal listeyi sorted(list)değiştirirken orijinal listeyi değiştirmeden listenin sıralanmış bir kopyasını döndürür.

  • Biri diğerine ne zaman tercih edilir?
  • Hangisi daha verimli? Ne kadar?
  • Bir liste list.sort()gerçekleştirildikten sonra sıralanmamış duruma geri döndürülebilir mi?

4
Eğer sorted()bir dize argümanını (yanlışlıkla) çağırırsanız dikkat edin ama bunun bir liste olduğunu düşünüyorsanız, bir dize değil, bir liste sonucu alırsınız : sorted("abcd", reverse=True)verir ['d', 'c', 'b', 'a']değil"dcba"
smci

Yanıtlar:


317

sorted()orijinal listeyi etkilemeden yeni bir sıralı liste döndürür . list.sort()listeyi sıralar yerinde dizinlerini değiştirir ve döndürür None(tüm yerinde işlemler gibi).

sorted()sadece listelerde değil, tüm yinelemelerde çalışır. Dizeler, tuples, sözlükler (anahtarları alırsınız), jeneratörler, vb. Sıralanır.

  • list.sort()Listeyi değiştirmek sorted()istediğinizde, yeni bir sıralanmış nesneyi geri istediğinizde kullanın . Henüzsorted() bir liste değil, tekrarlanabilir bir şeyi sıralamak istediğinizde kullanın .

  • Listeler için, kopya oluşturmak zorunda olmadığından list.sort()daha hızlıdır sorted(). Diğer yinelenebilirler için başka seçeneğiniz yok.

  • Hayır, orijinal konumları alamazsınız. Bir kez aradığınız list.sort()orijinal sipariş gitti.


6
Genel olarak, bir python işlevi döndüğünde None, işlemlerin yerinde yapıldığının bir işaretidir, bu nedenle yazdırmak istediğinizde list.sort()Yok döndürür.
user1767754

45

sorted(list)Vs arasındaki fark nedir list.sort()?

  • list.sort listeyi yerinde değiştirir ve geri döner None
  • sorted herhangi bir yinelenebilir alır ve sıralanmış yeni bir liste döndürür.

sorted bu Python uygulamasına eşdeğerdir, ancak CPython yerleşik işlevi C'de yazıldığından ölçülebilir şekilde daha hızlı çalışmalıdır:

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

ne zaman kullanılır?

  • kullanım list.sort orijinal sıralama düzenini korumak istemeyen zaman (Böylece. Bellekte yerinde listeyi yeniden mümkün olacak) ve (listedeki tek sahibi olduklarında liste diğer kod ve sizin tarafınızdan paylaşılıyorsa mutasyona uğrarsanız, bu listenin kullanıldığı hataları tanıtabilirsiniz.)
  • Kullan sortedorijinal sıralama düzenini korumak isteyen veya sadece yerel kod sahibi olduğu yeni bir liste oluşturmak istediğinizde.

Listenin orijinal konumları list.sort () öğesinden sonra alınabilir mi?

Hayır - kendiniz bir kopyasını yapmadıysanız, sıralama yerinde yapıldığından bu bilgiler kaybolur.

"Ve hangisi daha hızlı? Ve ne kadar daha hızlı?"

Yeni bir liste oluşturmanın cezasını göstermek için timeit modülünü kullanın, işte kurulumumuz:

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
"""

Ve burada gördüğümüz gibi rastgele düzenlenmiş 10000 tamsayı listesi için sonuçlarımız, daha eski bir liste oluşturma masrafı mitini çürütdük :

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]

Bazı geri bildirimlerden sonra, farklı özelliklere sahip başka bir testin isteneceğine karar verdim. Burada, her yineleme için 1000 kez aynı rastgele sıralı 100.000 uzunluk listesini sağlarım.

import timeit
setup = """
import random
random.seed(0)
lst = list(range(100000))
random.shuffle(lst)
"""

Bu daha büyük türün Martijn tarafından belirtilen kopyadan gelen farkını yorumluyorum, ancak burada daha eski daha popüler cevapta belirtilen noktaya hakim değil, burada zaman artışı sadece yaklaşık% 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]

Yukarıdakileri de çok daha küçük bir çeşitte çalıştırdım ve yeni sortedkopya versiyonunun 1000 çeşit bir çalışma süresinde hala% 2 daha uzun sürdüğünü gördüm .

Poke kendi kodunu da çalıştırdı, işte 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))

1000000 uzunluk sıralaması buldu, (100 kez koştu) benzer bir sonuç, ama zamanın sadece% 5'inde bir artış, çıktı:

10000000 100
l = next(it); l.sort()
610.5015971539542
l = next(it); sorted(l)
646.7786222379655

Sonuç:

Bir sortedkopya oluşturma ile sıralanan büyük boyutlu bir liste büyük olasılıkla farklılıklara hükmeder, ancak sıralamanın kendisi işleme hakim olur ve kodunuzu bu farklılıklar etrafında düzenlemek erken optimizasyon olacaktır. Ben kullanırım sortedben yeni bir veri sıralı liste gerektiğinde, ben kullanmak list.sortben yerinde bir liste sıralamak gerektiğinde ve bu benim kullanımını belirlemek edelim.


4
Jeneratör kurulumu güzel, ama bir efsaneyi çok çabuk yaktığın sonucuna varmam. Aslında kalıntılar sorted()Yeni bir liste nesnesi tahsis ve referansları kopyalamak zorundadır; kod yollarının geri kalanı aynıdır. Aynı testleri daha büyük listelerle yapıp yapamayacağınıza bakın. Sadece listelerin kopyalarını oluşturarak karşılaştırın ve bulduğunuz farklılıkları tekrarlayıp tekrarlayamayacağınızı görün.
Martijn Pieters

11

Temel fark, yenisorted(some_list) bir değer döndürmesidir :list

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

ve some_list.sort(), liste sıralar yerinde :

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

Not beri bu a.sort()şey dönmez, print a.sort()yazdırılacaktır None.


Bir liste orijinal konumları list.sort () öğesinden sonra alınabilir mi?

Hayır, çünkü orijinal listeyi değiştirir.


1
print a.sort()hiçbir şey yazdırmaz.
Burhan Khalid

1
Basılacak None, bunu netleştireceğim.
Christian

1

.Sort () işlevi yeni listenin değerini doğrudan liste değişkeninde saklar; üçüncü sorunuzun cevabı HAYIR olacaktır. Ayrıca bunu sıralama (list) kullanarak yaparsanız, bunu liste değişkeninde saklanmadığı için kullanabilirsiniz. Ayrıca bazen .sort () yöntemi işlev olarak işlev görür veya içinde argümanlar aldığını söyler.

Sıralanan (liste) değerini bir değişkende açıkça saklamanız gerekir.

Ayrıca kısa veri işleme için hızın hiçbir farkı olmayacaktır; ancak uzun listeler için; hızlı çalışma için doğrudan .sort () yöntemini kullanmalısınız; ama yine geri dönüşü olmayan eylemlerle karşılaşacaksınız.


".Sort () işlevi yeni listenin değerini doğrudan liste değişkeninde saklar" Ha? Hangi yeni liste? Yeni bir liste yok. list.sort()Yöntem yerinde liste nesnesi sıralar.
PM 2Ring

Ayrıca, bunun anlamı ne? "bazen .sort () yöntemi işlev olarak işlev görür veya içinde bağımsız değişkenler aldığını söyler."
PM 2Ring

Yeni liste ile ne demek istediğim değiştirilmiş liste ve .sort () sadece bu değiştirilmiş listeyi aynı değişkene depolar.
Vicrobot

Evet, kesinlikle bazen .sort()yöntem argüman alır ve işlev olarak hareket eder. Ayrıca, liste veri türünün bir özniteliği olduğu için buna yöntem diyoruz.
Vicrobot

Konseptimde bir tür hata varsa, o zaman söyle, bunu arayacağım ve kavramlarımı ve cevabımı da geliştireceğim. Teşekkürler
Vicrobot

1

Eylemdeki farkı görmek için birkaç basit örnek:

Buradaki numaraların listesine bakın:

nums = [1, 9, -3, 4, 8, 5, 7, 14]

sortedBu listeyi ararken listenin sortedbir kopyasını oluşturur. (Yani orijinal listeniz değişmeden kalacaktır.)

Bakalım.

sorted(nums)

İadeler

[-3, 1, 4, 5, 7, 8, 9, 14]

Baktığımızda numsAgain

nums

Orijinal listeyi görüyoruz (değiştirilmedi ve sıralanmadı.). sortedorijinal listeyi değiştirmedi

[1, 2, -3, 4, 8, 5, 7, 14]

Aynı numslistenin alınması ve sortfonksiyonun üzerine uygulanması , gerçek listeyi değiştirecektir.

Bakalım.

numsEmin olmak için listemizden başlayarak , içeriğin hala aynı olduğundan emin olun.

nums

[-3, 1, 4, 5, 7, 8, 9, 14]

nums.sort()

Şimdi orijinal nums listesi değişti ve orijinal listemizin değiştiğini ve şimdi sıralandığını gördüğümüz rakamlara baktığımızda.

nums
[-3, 1, 2, 4, 5, 7, 8, 14]

Orijinal ve kopyayı daha derinlemesine gösterdiğiniz için teşekkür ederiz
Brendan Metcalfe

0

Not: sort () ile sort () arasındaki en basit fark: sort () herhangi bir değer döndürmezken, sort () yinelenebilir bir liste döndürür.

sort () herhangi bir değer döndürmez.

Sort () yöntemi, belirli bir listenin öğelerini belirli bir sırayla sıralar - Herhangi bir değer döndürmeden Artan veya Azalan.

Sort () yönteminin sözdizimi:

list.sort(key=..., reverse=...)

Alternatif olarak, aynı amaçla Python'un yerleşik () sıralama işlevini de kullanabilirsiniz. sıralı işlev sıralı listeyi döndür

 list=sorted(list, key=..., reverse=...)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.