web-dev-qa-db-fra.com

Quelle est la différence entre `rangé (liste)` et `list.sort ()`

list.sort() trie la liste et enregistre la liste triée, tandis que sorted(list) renvoie une copie triée de la liste sans modifier la liste d'origine.

  • Mais quand utiliser lequel? 
  • Et qui est le plus rapide? Et combien plus vite?
  • Les positions d'origine d'une liste peuvent-elles être récupérées après list.sort()?
126
alvas

sorted() renvoie une liste triée nouvelle _, sans affecter la liste d'origine. list.sort() trie la liste sur place, mute les index de la liste et renvoie None (comme toutes les opérations sur place).

sorted() fonctionne sur n’importe quelle liste, pas seulement sur une liste. Des chaînes, des tuples, des dictionnaires (vous aurez les clés), des générateurs, etc., retournant une liste contenant tous les éléments, triés.

  • Utilisez list.sort() lorsque vous souhaitez modifier la liste, sorted() lorsque vous souhaitez récupérer un nouvel objet trié. Utilisez sorted() lorsque vous souhaitez trier un élément itératif, et non une liste yet.

  • Pour les listes, list.sort() est plus rapide que sorted() car il n'est pas nécessaire de créer une copie. Pour tout autre itérable, vous n'avez pas le choix.

  • Non, vous ne pouvez pas récupérer les positions d'origine. Une fois que vous avez appelé list.sort(), la commande initiale est partie.

220
Martijn Pieters

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

  • list.sort mute la liste sur place & renvoie None
  • sorted prend une valeur quelconque et renvoie une nouvelle liste, triée.

sorted est équivalent à cette implémentation de Python, mais la fonction intégrée de CPython devrait s'exécuter de manière mesurable plus rapidement car elle est écrite 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 d'origine .__ (vous pourrez ainsi réutiliser la liste en mémoire). Et lorsque Vous êtes l'unique propriétaire de la liste (si la liste est partagé par un autre code .__ et que vous le modifiez, vous pouvez introduire des bugs là où cette liste est utilisée.)
  • Utilisez sorted lorsque vous souhaitez conserver l'ordre de tri d'origine ou lorsque vous souhaitez créer une nouvelle liste que seul votre code local possède.

Les positions d'origine d'une liste peuvent-elles être récupérées après list.sort ()?

Non - sauf si vous en avez copié vous-même, cette information est perdue car le tri est effectué sur place.

"Et qui est le plus rapide? Et combien plus vite?"

Pour illustrer la pénalité liée à 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 de manière aléatoire, comme nous pouvons le voir ici, nous avons réfuté un ancien mythe de dépense 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 retours, j'ai décidé qu'un autre test serait souhaitable avec des caractéristiques différentes. Ici, je fournis la même liste ordonnée au hasard de 100 000 longueurs 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 ce type plus large 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 de temps n'est que d'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 également exécuté ce qui précède sur une sorte beaucoup plus petite et j'ai constaté que la nouvelle version de la copie sorted prend encore environ 2% de temps d'exécution en plus sur une sorte de longueur 1000.

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 le sort de longueur 1000000 (100 fois) un résultat similaire, mais avec une augmentation de temps d'environ 5%, voici le résultat:

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

Conclusion:

Une liste de grande taille triée avec sorted en faisant une copie dominera probablement les différences, mais le tri lui-même domine l'opération et l'organisation de votre code autour de ces différences constituerait une optimisation prématurée. Je voudrais utiliser sorted lorsque j'ai besoin d'une nouvelle liste triée des données, et list.sort lorsque j'ai besoin de trier une liste sur place, et laisser cela déterminer mon utilisation.

28
Aaron Hall

La principale différence est que sorted(some_list) renvoie un nouveau list:

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

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

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

Remarque puisque a.sort() ne renvoie rien, print a.sort() imprimera None.


Une liste des positions d'origine peut-elle être récupérée après list.sort ()?

Non, car cela modifie la liste d'origine.

8
Christian

La fonction .sort () stocke la valeur de nouvelle liste directement dans la variable de liste; Donc, si vous répondez à votre troisième question, la réponse est NON . De plus, si vous utilisez pour cela Trier (liste), vous pouvez le faire utiliser car il n’est pas stocké dans la liste. Parfois, la méthode .sort () agit comme une fonction ou indique qu’elle prend des arguments.

Vous devez stocker explicitement la valeur de Trier (liste) dans une variable.

De plus, pour un traitement de données court, la vitesse n'aura aucune différence. mais pour les longues listes; vous devez directement utiliser la méthode .sort () pour un travail rapide; mais encore une fois, vous ferez face à des actions irréversibles. 

1
Vicrobot

Remarque: La différence la plus simple entre sort () et trié () est: sort () ne retourne aucune valeur alors que, Trier () renvoie une liste itérable.

sort () ne renvoie aucune valeur.

La méthode sort () trie simplement les éléments d'une liste donnée dans un ordre spécifique - croissant ou décroissant sans renvoyer de valeur.

La syntaxe de la méthode sort () est la suivante:

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

Alternativement, vous pouvez également utiliser la fonction intégrée de Python, sort () dans le même but. fonction triée retourne la liste triée

 list=sorted(list, key=..., reverse=...)
0
Projesh Bhoumik

Voici quelques exemples simples pour voir la différence dans l'action:

Voir la liste des numéros ici:

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

Lorsque vous appelez sorted sur cette liste, sorted créera une copie de la liste. (Cela signifie que votre liste d'origine restera inchangée.)

Voyons voir.

sorted(nums)

résultats

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

En regardant à nouveau la nums

nums

Nous voyons la liste originale (inchangée et NON triée.). sorted n'a pas changé la liste d'origine

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

Prendre la même liste nums et y appliquer la fonction sort modifiera la liste actuelle. 

Voyons voir.

En commençant par notre liste nums, assurez-vous que le contenu est toujours le même.

nums

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

nums.sort()

Maintenant, la liste des numéros d'origine est modifiée et, en regardant les numéros, nous voyons que notre liste d'origine a été modifiée et triée. 

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