web-dev-qa-db-ja.com

`sorted(list)`と `list.sort()`の違いは何ですか?

list.sort()はリストをソートしてソートしたリストを保存しますが、sorted(list)は元のリストを変更せずにソートしたリストのコピーを返します。

  • しかし、いつどれを使用するのですか?
  • そして、どちらが速いですか?そして、どのくらい速くなりますか?
  • list.sort()の後にリストの元の位置を取得できますか?
148
alvas

sorted()newソート済みリストを返し、元のリストは影響を受けません。 list.sort()は、リストをソートしますin-place、リストインデックスを変更し、Noneを返します(すべてのインプレース操作と同様)。

sorted()は、リストだけでなく、あらゆる反復可能オブジェクトで機能します。ストリング、タプル、辞書(キーを取得します)、ジェネレーターなど。すべての要素を含むリストをソートして返します。

  • リストを変更する場合はlist.sort()を使用し、新しいソート済みオブジェクトを戻す場合はsorted()を使用します。リストではなく反復可能なものをソートする場合は、sorted()を使用しますyet

  • リストの場合、list.sort()はコピーを作成する必要がないため、sorted()よりも高速です。他の反復​​可能なものについては、選択肢がありません。

  • いいえ、元の位置を取得することはできません。 list.sort()を呼び出すと、元の順序はなくなります。

244
Martijn Pieters

sorted(list)list.sort()の違いは何ですか?

  • list.sortはリストをインプレースで変更し、Noneを返します
  • sortedは、反復可能なものを取り、ソートされた新しいリストを返します。

sortedはこのPython実装と同等ですが、CPython組み込み関数は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

いつ使用するか?

  • 元のソート順を保持したくない場合(したがって、メモリ内のリストをインプレースで再利用できます)、およびリストの唯一の所有者である場合(リストが他のコードと共有されている場合、list.sortを使用します。それを変更すると、そのリストが使用されているバグを導入することができます。)
  • 元のソート順を保持する場合、またはローカルコードのみが所有する新しいリストを作成する場合は、sortedを使用します。

List.sort()の後にリストの元の位置を取得できますか?

いいえ-自分でコピーを作成しない限り、ソートはインプレースで行われるため、その情報は失われます。

「そして、どちらが速いですか?そしてどれくらい速いですか?

新しいリストを作成することのペナルティを説明するには、timeitモジュールを使用します。セットアップは次のとおりです。

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

ランダムに配置された10000個の整数のリストの結果は次のとおりです。ここでわかるように、 古いリスト作成費用の神話

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]

いくつかのフィードバックの後、異なる特性を備えた別のテストが望ましいと判断しました。ここでは、反復ごとに1,000回、長さ100,000の同じランダムに並べられたリストを提供します。

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

私はマーティンが言及したコピーから来るこの大きな種類の違いを解釈しますが、それはここでより古いより一般的な答えで述べられたポイントを支配しません、ここで時間の増加はわずか約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]

また、上記をはるかに小さいソートで実行しましたが、新しいsortedコピーバージョンでは、1000の長さのソートで実行時間が約2%長くなることがわかりました。

Pokeは彼自身のコードも実行しました。コードは次のとおりです。

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の長さの並べ替え(100回実行)で同様の結果を見つけましたが、時間は約5%しか増加していません。出力は次のとおりです。

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

結論:

コピーを作成するsortedでソートされた大きなサイズのリストはおそらく違いを支配しますが、ソート自体が操作を支配し、これらの違いを中心にコードを編成することは時期尚早の最適化になります。データの新しい並べ替えられたリストが必要な場合はsortedを使用し、リストをインプレースで並べ替える必要がある場合はlist.sortを使用し、それで使用方法を決定します。

32
Aaron Hall

主な違いは、sorted(some_list)new listを返すことです。

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

およびsome_list.sort()リストを並べ替えますin place

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

a.sort()は何も返さないため、print a.sort()Noneを出力します。


list.sort()の後にリストの元の位置を取得できますか?

いいえ、元のリストを変更するためです。

9
Christian

.sort()関数は、新しいリストの値をリスト変数に直接保存します。 3番目の質問に対する答えは「いいえ」になります。また、sorted(list)を使用してこれを行うと、リスト変数に格納されないため、使用できます。また、.sort()メソッドが関数として機能する場合や、引数をとると言う場合もあります。

Sort(list)の値を明示的に変数に保存する必要があります。

また、短いデータ処理の場合、速度に違いはありません。ただし、長いリストの場合。作業を高速化するには、.sort()メソッドを直接使用する必要があります。しかし、あなたは不可逆的な行動に直面するでしょう。

0
Vicrobot

注:sort()とsort()の最も単純な違いは、sort()は値を返さない一方で、sorted()は反復可能なリストを返すことです。

sort()は値を返しません。

Sort()メソッドは、指定されたリストの要素を特定の順序(値を返さずに昇順または降順)で並べ替えるだけです。

Sort()メソッドの構文は次のとおりです。

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

または、同じ目的でPythonの組み込み関数sort()を使用することもできます。ソート済み関数はソート済みリストを返します

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

次に、アクションの違いを確認するための簡単な例をいくつか示します。

数字のリストはこちらをご覧ください:

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

このリストでsortedを呼び出すと、sortedはリストのcopyを作成します。 (元のリストの意味は変更されません。)

どれどれ。

sorted(nums)

返す

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

numsをもう一度見る

nums

元のリストが表示されます(変更されておらず、ソートされていません)。 sortedは元のリストを変更しませんでした

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

同じnumsリストを取得し、それにsort関数を適用すると、実際のリストが変更されます。

どれどれ。

確認するためにnumsリストから始めて、内容は同じままです。

nums

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

nums.sort()

元のnumsリストが変更され、numsを見ると、元のリストが変更され、ソートされていることがわかります。

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