Quelle est la différence entre " triés(liste)` vs `liste.sort ()'?

list.sort() trie la liste et sauve la liste triée, tandis que sorted(list) retourne une copie triée de la liste, sans changer la liste originale.

  • mais quand utiliser?
  • et qui est le plus rapide? Et comment beaucoup plus rapide?
  • peut-on retrouver les positions originales d'une liste après list.sort() ?
110
demandé sur smci 2014-03-17 00:16:10

4 réponses

sorted() retourne une nouvelle liste triée, laissant la liste originale inchangée. list.sort() trie la liste en place , Mutant les indices de liste, et renvoie None (comme toutes les opérations en place).

sorted() fonctionne sur n'importe quelle itérable, pas seulement des listes. Les chaînes, tuples, des dictionnaires (vous aurez les clés), générateurs, etc. en renvoyant une liste contenant tous les éléments triés.

  • utilisez list.sort() lorsque vous voulez modifier la liste, sorted() lorsque vous voulez récupérer un nouvel objet trié. Utilisez sorted() quand vous voulez trier quelque chose qui est un itérable, pas une liste encore .

  • pour les listes, list.sort() est plus rapide que sorted() parce qu'il n'a pas à créer de copie. Pour toute autre itérable, vous n'avez pas le choix.

  • Non, vous ne pouvez pas récupérer les positions originales. Une fois que vous avez appelé list.sort() l'ordre original est parti.

187
répondu Martijn Pieters 2016-09-25 08:34:54

Quelle est la différence entre sorted(list) vs list.sort() ?

  • list.sort mute la liste sur place & retours None
  • sorted prend n'importe quelle itérable et renvoie une nouvelle liste, triée.

sorted est l'équivalent de cette implémentation Python, mais la fonction intégrée de CPython devrait fonctionner plus rapidement de façon mesurable comme il est écrit en 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

quand utiliser lequel?

  • utilisez list.sort lorsque vous ne souhaitez pas conserver l'ordre de tri original (Vous pourrez ainsi réutiliser la liste en mémoire.) et quand vous êtes le propriétaire unique de la liste (si celle-ci est partagée par d'autres et si vous la mutez, vous pourriez introduire des bogues là où cette liste est utilisée.)
  • utilisez sorted lorsque vous voulez conserver l'ordre de tri d'origine ou lorsque vous souhaitez créer une nouvelle liste que seul votre code local est propriétaire.

peut les positions originales d'une Liste être récupérées après la liste.sort()?

Non-sauf si vous avez fait une copie vous-même, cette information est perdue parce que le tri est fait sur place.

" et qui est le plus rapide? Et comment beaucoup plus rapide?"

à illustrer la pénalité de la création d'une nouvelle liste, utilisez le module timeit, voici notre configuration:

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

et voici nos résultats pour une liste de 10000 entiers arrangés au hasard, comme nous pouvons le voir ici, nous avons réfuté un vieux mythe de dépenses de création de liste :

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]

après quelques commentaires, je décidé un autre test serait souhaitable, avec des caractéristiques différentes. Ici, je fournis la même liste aléatoire de 100.000 de longueur pour chaque itération 1.000 fois.

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

j'interprète la différence de cette sorte plus grande provenant de la copie mentionnée par Martijn, mais elle ne domine pas au point indiqué dans la réponse plus ancienne plus populaire ici, ici l'augmentation du temps est seulement environ 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]

j'ai aussi couru ci-dessus une sorte beaucoup plus petite, et a vu que la nouvelle version de copie sorted prend encore environ 2% plus de temps de fonctionnement sur une sorte de 1000 longueur.

Poke a aussi lancé son propre code, Voici le code:

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

il a trouvé pour 1000000 longueur tri, (couru 100 fois) un résultat similaire, mais seulement environ 5% d'augmentation dans le temps, voici la sortie:

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

Conclusion:

une liste de grande taille étant trié avec sorted faire une copie dominera probablement les différences, mais le tri lui-même domine l'opération, et organiser votre code autour de ces différences serait une optimisation prématurée. J'utiliserais sorted quand j'aurais besoin d'une nouvelle liste triée des données, et j'utiliserais list.sort quand j'aurais besoin de trier une liste en place, et laisser cela déterminer mon usage.

26
répondu Aaron Hall 2018-07-25 21:20:53

la principale différence est que sorted(some_list) retourne un nouveau list :

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

et some_list.sort() , trie la liste en place :

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

Note que puisque a.sort() ne retourne rien, print a.sort() affichera None .


une liste les positions originales doivent être retrouvées après la liste.sort()?

non, parce qu'il modifie la liste originale.

7
répondu Christian 2014-03-16 20:19:46

The .la fonction sort() stocke la valeur de la nouvelle liste directement dans la variable list; donc la réponse à votre troisième question serait non. Aussi si vous faites cela en utilisant tried (list), alors vous pouvez obtenir l'utilisation parce qu'elle n'est pas stockée dans la variable list. Aussi parfois .la méthode sort() agit comme fonction, ou dit qu'elle prend des arguments en elle.

vous devez stocker la valeur de tried(list) dans une variable explicitement.

également pour le traitement des données vitesse aura pas de différence, mais pour les longues listes; vous devriez les utiliser directement .tri() méthode pour le travail rapide; mais encore une fois, vous devrez faire face à des actions irréversibles.

1
répondu Vicrobot 2018-04-01 14:53:48