Pythonでsorted()およびsort()を使用する方法

Pythonでsorted()およびsort()を使用する方法

すべてのプログラマは、ある時点でアイテムまたはデータをソートするコードを作成する必要があります。 並べ替えは、ユーザーの最新のアクティビティをタイムスタンプで並べ替える場合でも、メール受信者のリストを姓のアルファベット順に並べる場合でも、アプリケーションのユーザーエクスペリエンスにとって重要です。 Pythonの並べ替え機能は、基本的な並べ替えを実行したり、詳細なレベルで順序をカスタマイズしたりするための堅牢な機能を提供します。

このガイドでは、さまざまなデータ構造のさまざまな種類のデータを並べ替える方法、順序をカスタマイズする方法、およびPythonで2つの異なる並べ替え方法を操作する方法を学習します。

このチュートリアルの終わりまでに、次の方法を理解できます。

  • データ構造に基本的なPythonの並べ替えと順序付けを実装する

  • `+ sorted()`と ` .sort()+`を区別する

  • 固有の要件に基づいてコード内の複雑なソート順をカスタマイズします

このチュートリアルでは、https://realpython.com/python-lists-tuples/[lists and tuples]およびhttps://realpython.com/quizzes/python-sets/[setsの基本的な理解が必要です。 ]。 これらのデータ構造はこのチュートリアルで使用され、いくつかの基本的な操作が実行されます。 また、このチュートリアルではPython 3を使用しているため、Python 2を使用している場合、このチュートリアルの出力例は若干異なる場合があります。

*無料ボーナス:*リンク:[Python Tricks:The Book]の章にアクセスするには、ここをクリックして、Pythonのベストプラクティスを簡単な例とともに示します。すぐに適用して、より美しい+ Pythonコードを記述できます。

`+ sorted()+`による値の順序付け

Pythonの並べ替えを開始するには、まず数値データと文字列データの両方を並べ替える方法を確認します。

番号の並べ替え

Pythonを使用して、 `+ sorted()`を使用してリストをソートできます。 この例では、整数のリストが定義され、引数として ` numbers `変数を使用して ` sorted()+`が呼び出されます:

>>>

>>> numbers = [6, 9, 3, 1]
>>> sorted(numbers)
[1, 3, 6, 9]
>>> numbers
[6, 9, 3, 1]

このコードからの出力は、新しいソートされたリストです。 元の変数が出力されると、初期値は変更されません。

この例は、 `+ sorted()+`の4つの重要な特性を示しています。

  1. 関数 `+ sorted()+`を定義する必要はありませんでした。 Pythonの標準インストールで利用可能な組み込み関数です。

  2. 追加の引数やパラメータなしの `+ sorted()`は、 ` numbers +`の値を昇順、つまり最小から最大の順に並べています。

  3. 元の `+ numbers `変数は変更されません。これは、 ` sorted()+`がソートされた出力を提供し、元の値を変更しないためです。

  4. `+ sorted()+`が呼び出されると、順序付けられたリストを戻り値として提供します。

この最後のポイントは、リストで `+ sorted()+`を使用でき、出力をすぐに変数に割り当てることができることを意味します。

>>>

>>> numbers = [6, 9, 3, 1]
>>> numbers_sorted = sorted(numbers)
>>> numbers_sorted
[1, 3, 6, 9]
>>> numbers
[6, 9, 3, 1]

この例では、 `+ sorted()`の出力を保存する新しい変数 ` numbers_sorted +`があります。

`+ sorted()`で ` help()`を呼び出すことで、これらすべての観察結果を確認できます。 オプションの引数 ` key `と ` reverse +`は、チュートリアルの後半で説明します。

>>>

>>> # Python 3
>>> help(sorted)
Help on built-in function sorted in module builtins:

sorted(iterable,/, *, key=None, reverse=False)
    Return a new list containing all items from the iterable in ascending order.

    A custom key function can be supplied to customize the sort order, and the
    reverse flag can be set to request the result in descending order.

技術的な詳細: Python 2から移行し、同じ名前の機能に精通している場合は、Python 3のいくつかの重要な変更点に注意してください。

  1. Python 3の `+ sorted()`には ` cmp `パラメータがありません。 代わりに、カスタムソートロジックを導入するために「 key +」のみが使用されます。

  2. `+ key `と ` reverse +`は、位置引数として渡すことができるPython 2とは異なり、キーワード引数として渡す必要があります。

Python 2の `+ cmp `関数を ` key `関数に変換する必要がある場合は、 ` functools.cmp_to_key()+`をチェックしてください。 このチュートリアルでは、Python 2を使用した例を取り上げません。

`+ sorted()+`はタプルで使用でき、非常によく似ています:

>>>

>>> numbers_tuple = (6, 9, 3, 1)
>>> numbers_set = {5, 5, 10, 1, 0}
>>> numbers_tuple_sorted = sorted(numbers_tuple)
>>> numbers_set_sorted = sorted(numbers_set)
>>> numbers_tuple_sorted
[1, 3, 6, 9]
>>> numbers_set_sorted
[0, 1, 5, 10]

`+ sorted()+`は定義により新しいリストを返すため、入力がセットとタプルであったとしても、出力はリストであることに注意してください。 返されたオブジェクトは、入力タイプと一致する必要がある場合、新しいタイプにキャストできます。 定義によるセットは順序付けられていないため、結果のリストをセットにキャストしようとする場合は注意してください。

>>>

>>> numbers_tuple = (6, 9, 3, 1)
>>> numbers_set = {5, 5, 10, 1, 0}
>>> numbers_tuple_sorted = sorted(numbers_tuple)
>>> numbers_set_sorted = sorted(numbers_set)
>>> numbers_tuple_sorted
[1, 3, 6, 9]
>>> numbers_set_sorted
[0, 1, 5, 10]
>>> tuple(numbers_tuple_sorted)
(1, 3, 6, 9)
>>> set(numbers_set_sorted)
{0, 1, 10, 5}

`+ set `にキャストされたときの ` numbers_set_sorted `の値は、期待どおりに順序付けられていません。 他の変数 ` numbers_tuple_sorted +`は、ソートされた順序を保持しました。

文字列の並べ替え

`+ str `タイプは、リストやタプルのような他のイテラブルと同様にソートされます。 以下の例は、 ` sorted()+`が渡された値の各文字を反復処理し、出力でそれらを順序付けする方法を示しています。

>>>

>>> string_number_value = '34521'
>>> string_value = 'I like to sort'
>>> sorted_string_number = sorted(string_number_value)
>>> sorted_string = sorted(string_value)
>>> sorted_string_number
['1', '2', '3', '4', '5']
>>> sorted_string
[' ', ' ', ' ', 'I', 'e', 'i', 'k', 'l', 'o', 'o', 'r', 's', 't', 't']

`+ sorted()`は ` str `をリストのように扱い、各要素を繰り返し処理します。 ` str `では、各要素は ` str `の各文字を意味します。 ` sorted()+`は文の扱いを変えず、スペースを含む各文字をソートします。

`+ .split()`はこの動作を変更して出力をクリーンアップでき、 ` .join()+`はすべてを元に戻すことができます。 出力の特定の順序と、その理由がすぐに説明されます。

>>>

>>> string_value = 'I like to sort'
>>> sorted_string = sorted(string_value.split())
>>> sorted_string
['I', 'like', 'sort', 'to']
>>> ' '.join(sorted_string)
'I like sort to'

この例の元の文は、 `+ str `のままにするのではなく、単語のリストに変換されます。 そのリストはソートされ、リストの代わりに再び ` str +`を形成するために結合されます。

Pythonソートの制限事項と落とし穴

Pythonを使用して整数以外の値を並べ替えるときに発生する可能性のある制限と奇妙な動作に注意する価値があります。

比較できないデータ型のリストは `+ sorted()+`にはできません

`+ sorted()`だけでは比較できないデータタイプがあります。 比較できないデータを含むリストで ` sorted()`を使用しようとすると、Pythonはエラーを返します。 この例では、同じリスト内の「 None 」と「 int +」は互換性がないためソートできません。

>>>

>>> mixed_types = [None, 0]
>>> sorted(mixed_types)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'int' and 'NoneType'

このエラーは、与えられた値をPythonがソートできない理由を示しています。 小なり演算子( + <+)を使用して値を並べ、並べ替え順序で低い値を決定しようとしています。 2つの値を手動で比較することにより、このエラーを再現できます。

>>>

>>> None < 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'NoneType' and 'int'

`+ sorted()`を使用せずに2つの比較できない値を比較しようとすると、同じ ` TypeError +`がスローされます。

リスト内の値を比較でき、 `+ TypeError +`がスローされない場合、リストをソートできます。 これにより、本質的に順序付け不可能な値でイテラブルがソートされ、意味のない出力が生成されるのを防ぎます。

たとえば、「+ 1+」という数字は「+ apple +」という単語の前に来る必要がありますか? ただし、すべてが数字である整数と文字列の組み合わせがイテラブルに含まれる場合、リスト内包表記を使用して、同等のデータ型にキャストできます。

>>>

>>> mixed_numbers = [5, "1", 100, "34"]
>>> sorted(mixed_numbers)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'str' and 'int'
>>> # List comprehension to convert all values to integers
>>> [int(x) for x in mixed_numbers]
[5, 1, 100, 34]
>>> sorted([int(x) for x in mixed_numbers])
[1, 5, 34, 100]

`+ mixed_numbers `の各要素には ` int()`が呼び出され、 ` str `値を ` int `値に変換します。 次に、 ` sorted()+`が呼び出され、各要素を正常に比較して、ソートされた出力を提供できます。

Pythonは、値を暗黙的に別の型に変換することもできます。 以下の例では、 `+ 1 ⇐ 0 `の評価は偽のステートメントであるため、評価の出力は ` False `になります。 数値「+1」は「+ bool 」タイプとして「 True 」に変換でき、「 0+」は「+ False +」に変換できます。

リスト内の要素は異なって見えますが、すべてブール値( + True +`または `+ False +)に変換し、 `+ sorted()+`を使用して互いに比較できます。

>>>

>>> similar_values = [False, 0, 1, 'A' == 'B', 1 <= 0]
>>> sorted(similar_values)
[False, 0, False, False, 1]

`+ 'A' == 'B' `および `+1 <= 0 +`は ` False +`に変換され、順序付けられた出力で返されます。

この例は、ソートの重要な側面である sort stable を示しています。 Pythonでは、等しい値を並べ替えると、出力の元の順序が保持されます。 「1」が移動しても、他のすべての値は等しいため、互いに対する元の順序が保持されます。 以下の例では、すべての値は等しいと見なされ、元の位置を保持します。

>>>

>>> false_values = [False, 0, 0, 1 == 2, 0, False, False]
>>> sorted(false_values)
[False, 0, 0, False, 0, False, False]

元の順序とソートされた出力を調べると、 `+ 1 == 2 `が ` False +`に変換され、すべてのソートされた出力が元の順序になっていることがわかります。

文字列を並べ替えるとき、大事なこと

文字列のリストで `+ sorted()+`を使用して、デフォルトでアルファベット順に表示される昇順で値をソートできます。

>>>

>>> names = ['Harry', 'Suzy', 'Al', 'Mark']
>>> sorted(names)
['Al', 'Harry', 'Mark', 'Suzy']

ただし、Pythonは各文字列の最初の文字のhttps://en.wikipedia.org/wiki/Code_point[Unicode Code Point]を使用して、昇順のソート順を決定しています。 これは、 `+ sorted()`が ` Al `と ` al `の名前を同じように扱わないことを意味します。 この例では、 ` ord()+`を使用して、各文字列の最初の文字のUnicodeコードポイントを返します。

>>>

>>> names_with_case = ['harry', 'Suzy', 'al', 'Mark']
>>> sorted(names_with_case)
['Mark', 'Suzy', 'al', 'harry']
>>> # List comprehension for Unicode Code Point of first letter in each word
>>> [(ord(name[0]), name[0]) for name in sorted(names_with_case)]
[(77, 'M'), (83, 'S'), (97, 'a'), (104, 'h')]

`+ name [0] `は ` sorted(names_with_case)`の各要素の最初の文字を返し、 ` ord()`はUnicodeコードポイントを提供します。 アルファベットで「 a 」が「 M 」の前にある場合でも、「 M 」のコードポイントは「 a 」の前にあるため、ソートされた出力は最初に「 M +」になります。

最初の文字が同じ場合、 `+ sorted()+`は2番目の文字を使用して順序を決定し、それが同じ場合は3番目の文字を使用して、文字列の最後まで続きます。

>>>

>>> very_similar_strs = ['hhhhhd', 'hhhhha', 'hhhhhc','hhhhhb']
>>> sorted(very_similar_strs)
['hhhhha', 'hhhhhb', 'hhhhhc', 'hhhhhd']

`+ very_similar_strs `の各値は、最後の文字を除いて同一です。 ` sorted()+`は文字列を比較し、最初の5文字が同じであるため、出力は6番目の文字に基づいています。

同一の値を含む文字列は、短い文字列が長い文字列と比較する要素を持たないため、最短から最長にソートされます。

>>>

>>> different_lengths = ['hhhh', 'hh', 'hhhhh','h']
>>> sorted(different_lengths)
['h', 'hh', 'hhhh', 'hhhhh']

最短の文字列「+ h 」が最初に並べられ、最長の文字列「 hhhhh +」が最後に並べられます。

`+ reverse `引数で ` sorted()+`を使用する

`+ sorted()`の ` help()`ドキュメントに示されているように、 ` reverse `と呼ばれるオプションのキーワード引数があり、割り当てられたブール値に基づいてソート動作を変更します。 ` reverse `に ` True +`が割り当てられている場合、ソートは降順になります。

>>>

>>> names = ['Harry', 'Suzy', 'Al', 'Mark']
>>> sorted(names)
['Al', 'Harry', 'Mark', 'Suzy']
>>> sorted(names, reverse=True)
['Suzy', 'Mark', 'Harry', 'Al']

ソートのロジックは同じままです。つまり、名前はまだ最初の文字でソートされています。 しかし、出力は `+ reverse `キーワードを ` True +`に設定して反転されています。

「+ False 」が割り当てられている場合、順序は昇順のままになります。 前の例のいずれかを使用して、 ` True `または ` False +`の両方を使用してリバースの動作を確認できます。

>>>

>>> names_with_case = ['harry', 'Suzy', 'al', 'Mark']
>>> sorted(names_with_case, reverse=True)
['harry', 'al', 'Suzy', 'Mark']
>>> similar_values = [False, 1, 'A' == 'B', 1 <= 0]
>>> sorted(similar_values, reverse=True)
[1, False, False, False]
>>> numbers = [6, 9, 3, 1]
>>> sorted(numbers, reverse=False)
[1, 3, 6, 9]

+ key +`引数付きの `+ sorted()+

`+ sorted()`の最も強力なコンポーネントの1つは、 ` key +`と呼ばれるキーワード引数です。 この引数は関数が渡されることを想定しており、その関数はソートされるリストの各値で使用され、結果の順序を決定します。

基本的な例を示すために、特定のリストを順序付けるための要件は、リスト内の文字列の長さであり、最短から最長であると仮定しましょう。 文字列の長さを返す関数 `+ len()`は、 ` key +`引数とともに使用されます:

>>>

>>> word = 'paper'
>>> len(word)
5
>>> words = ['banana', 'pie', 'Washington', 'book']
>>> sorted(words, key=len)
['pie', 'book', 'banana', 'Washington']

結果の順序は、文字列の順序が最短から最長のリストです。 リスト内の各要素の長さは、 `+ len()+`によって決定され、昇順で返されます。

大文字と小文字が異なる場合、最初の文字でソートする前の例に戻りましょう。 文字列全体を小文字に変換することにより、 `+ key +`を使用してその問題を解決できます。

>>>

>>> names_with_case = ['harry', 'Suzy', 'al', 'Mark']
>>> sorted(names_with_case)
['Mark', 'Suzy', 'al', 'harry']
>>> sorted(names_with_case, key=str.lower)
['al', 'harry', 'Mark', 'Suzy']

`+ key `は元のリストのデータを操作しないため、出力値は小文字に変換されていません。 ソート中、 ` key +`に渡された関数は各要素で呼び出されてソート順を決定しますが、元の値は出力に含まれます。

`+ key +`引数付きの関数を使用する場合、主に2つの制限があります。

まず、 `+ key +`に渡される関数に必要な引数の数は1つでなければなりません。

以下の例は、2つの引数を取る加算関数の定義を示しています。 その関数が数値のリストの `+ key `で使用されると、2番目の引数が欠落しているため失敗します。 ソート中に ` add()+`が呼び出されるたびに、リストから一度に1つの要素のみを受け取ります。

>>>

>>> def add(x, y):
...     return x + y
...
>>> values_to_add = [1, 2, 3]
>>> sorted(values_to_add, key=add)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() missing 1 required positional argument: 'y'

2番目の制限は、 `+ key `で使用される関数が反復可能オブジェクトのすべての値を処理できる必要があることです。 たとえば、 ` sorted()`で使用される文字列として表される数値のリストがあり、 ` key `は ` int +`を使用して数値を数値に変換しようとします。 iterableの値を整数にキャストできない場合、関数は失敗します:

>>>

>>> values_to_cast = ['1', '2', '3', 'four']
>>> sorted(values_to_cast, key=int)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'four'

「+ str 」としての各数値は「 int 」に変換できますが、「 four 」は変換できません。 これにより、「 ValueError 」が発生し、無効であるため「 four 」を「 int +」に変換できないことを説明します。

組み込みまたはユーザー定義のほとんどすべての関数を使用して出力順序を操作できるため、 `+ key +`機能は非常に強力です。

順序付けの要件が、各文字列の最後の文字で反復可能なものを順序付けすることである場合(および文字が同じ場合は次の文字を使用する)、https://realpython.com/lessons/example-function/[関数]を定義して、ソートで使用できます。 以下の例は、渡された文字列を逆にする関数を定義し、その関数は `+ key +`の引数として使用されます:

>>>

>>> def reverse_word(word):
...     return word[::-1]
...
>>> words = ['banana', 'pie', 'Washington', 'book']
>>> sorted(words, key=reverse_word)
['banana', 'pie', 'book', 'Washington']

文字列を反転するには、 `+ word [::-1] `スライス構文が使用されます。 各要素には ` reverse_word()+`が適用され、ソート順は後方ワードの文字に基づきます。

スタンドアロン関数を書く代わりに、 `+ key `引数で定義された ` lambda +`関数を使用できます。

`+ lambda +`は以下の匿名関数です:

  1. インラインで定義する必要があります

  2. 名前がない

  3. statementsを含めることはできません

  4. 関数のように実行されます

以下の例では、「+ key 」は名前のない「 lambda 」として定義され、「 lambda 」が取る引数は「 x 」であり、「 x [::-1] +」は引数に対して実行される操作:

>>>

>>> words = ['banana', 'pie', 'Washington', 'book']
>>> sorted(words, key=lambda x: x[::-1])
['banana', 'pie', 'book', 'Washington']

`+ x [::-1] +`は各要素で呼び出され、単語を反転します。 その逆の出力はソートに使用されますが、元の単語は引き続き返されます。

要件が変更され、順序も逆にする必要がある場合は、 `+ key `引数とともに ` reverse +`キーワードを使用できます。

>>>

>>> words = ['banana', 'pie', 'Washington', 'book']
>>> sorted(words, key=lambda x: x[::-1], reverse=True)
['Washington', 'book', 'pie', 'banana']

`+ lambda `関数は、プロパティに基づいて ` class `オブジェクトをソートする必要がある場合にも役立ちます。 生徒のグループがあり、最終成績で最高から最低まで並べ替える必要がある場合、 ` lambda `を使用して ` class `から ` grade +`プロパティを取得できます。

>>>

>>> from collections import namedtuple

>>> StudentFinal = namedtuple('StudentFinal', 'name grade')
>>> bill = StudentFinal('Bill', 90)
>>> patty = StudentFinal('Patty', 94)
>>> bart = StudentFinal('Bart', 89)
>>> students = [bill, patty, bart]
>>> sorted(students, key=lambda x: getattr(x, 'grade'), reverse=True)
[StudentFinal(name='Patty', grade=94), StudentFinal(name='Bill', grade=90), StudentFinal(name='Bart', grade=89)]

この例では、 `+ namedtuple `を使用して、 ` name `および ` grade `属性を持つクラスを生成します。 ` lambda `は各要素で ` getattr()`を呼び出し、 ` grade +`の値を返します。

「+ reverse 」は「 True +」に設定され、昇順の出力が反転して降順になり、最高のグレードが最初に順序付けられます。

`+ sorted()`で ` key `と ` reverse `の両方のキーワード引数を利用する場合、どのように順序付けを行うことができるかは無限です。 小さな関数に基本的な ` lambda +`を使用する場合、コードを簡潔かつ短く保つことができます。または、まったく新しい関数を記述してインポートし、キー引数で使用することもできます。

`+ .sort()+`による値の順序付け

非常によく似た名前の `+ .sort()`は、組み込みの ` sorted()`とはかなり異なります。 ほぼ同じことを達成しますが、 ` list.sort()`の ` help()`ドキュメントは、 ` .sort()`と ` sorted( )+ `:

>>>

>>> # Python2
Help on method_descriptor:

sort(...)
    L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
    cmp(x, y) -> -1, 0, 1

>>> # Python3
>>> help(list.sort)
Help on method_descriptor:

sort(...)
    L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*

まず、ソートは `+ list +`クラスのメソッドであり、リストでのみ使用できます。 iterableが渡されるビルトインではありません。

次に、 `+ .sort()`は ` None +`を返し、その場で値を変更します。 コードのこれらの違いの両方の影響を見てみましょう。

>>>

>>> values_to_sort = [5, 2, 6, 1]
>>> # Try to call .sort() like sorted()
>>> sort(values_to_sort)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sort' is not defined

>>> # Try to use .sort() on a tuple
>>> tuple_val = (5, 1, 3, 5)
>>> tuple_val.sort()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'sort'

>>> # Sort the list and assign to new variable
>>> sorted_values = values_to_sort.sort()
>>> print(sorted_values)
None

>>> # Print original variable
>>> print(values_to_sort)
[1, 2, 5, 6]

このコード例では、 `+ .sort()`の動作と ` sorted()+`の動作には、かなり劇的な違いがいくつかあります。

  1. `+ .sort()`の順序付けられた出力はないため、新しい変数への割り当ては ` None +`型のみを渡します。

  2. `+ values_to_sort +`リストはその場で変更されており、元の順序は一切維持されていません。

これらの動作の違いにより、 `+ .sort()`と ` sorted()+`はコード内で完全に互換性がなくなり、間違った方法で使用すると予想外の結果が生じる可能性があります。

`+ .sort()`には、 ` sorted()`と同じ堅牢な機能を生成する、同じ ` key `および ` reverse +`オプションのキーワード引数があります。 ここでは、フレーズのリストを3番目の単語の2番目の文字でソートし、リストを逆順に返すことができます。

>>>

>>> phrases = ['when in rome',
...     'what goes around comes around',
...     'all is fair in love and war'
...     ]
>>> phrases.sort(key=lambda x: x.split()[2][1], reverse=True)
>>> phrases
['what goes around comes around', 'when in rome', 'all is fair in love and war']

このサンプルでは、​​「+ lambda +」を使用して以下を実行します。

  1. 各フレーズを単語のリストに分割します

  2. 3番目の要素、この場合は単語を見つける

  3. その単語の2番目の文字を見つける

`+ sorted()`を使用する場合と ` .sort()+`を使用する場合

`+ sorted()`と ` .sort()+`の違いを見てきましたが、いつどちらを使用しますか?

5kのレースが近づいているとしましょう:The First Annual Python 5k。 レースのデータをキャプチャして並べ替える必要があります。 キャプチャする必要があるデータは、ランナーのゼッケン番号とレースを終了するのにかかった秒数です。

>>>

>>> from collections import namedtuple

>>> Runner = namedtuple('Runner', 'bibnumber duration')

ランナーがフィニッシュラインを越えると、各「+ Runner 」が「 runners +」というリストに追加されます。 5kレースでは、すべてのランナーが同時にスタートラインを通過するわけではないため、フィニッシュラインを最初に通過する人が実際には最速の人ではない場合があります。

>>>

>>> runners = []
>>> runners.append(Runner('2528567', 1500))
>>> runners.append(Runner('7575234', 1420))
>>> runners.append(Runner('2666234', 1600))
>>> runners.append(Runner('2425234', 1490))
>>> runners.append(Runner('1235234', 1620))
>>> # Thousands and Thousands of entries later...
>>> runners.append(Runner('2526674', 1906))

ランナーがフィニッシュラインを超えるたびに、ビブ番号と秒単位の合計継続時間が「+ runners +」に追加されます。

現在、結果データの処理を担当する忠実なプログラマーはこのリストを見て、上位5位までの参加者が賞品を獲得した勝者であり、残りのランナーは最速時間でソートされることを知っています。

さまざまな属性による複数の種類のソートの要件はありません。 リストは妥当なサイズです。 リストをどこかに保存することについての言及はありません。 期間で並べ替えて、期間が最も短い5人の参加者を取得します。

>>>

>>> runners.sort(key=lambda x: getattr(x, 'duration'))
>>> top_five_runners = runners[:5]

プログラマーは、各ランナーから「+ duration 」属性を取得し、「。sort()」を使用して「 runners 」を所定の位置にソートするために、「 key 」引数で「 lambda 」を使用することを選択します。 ` runners `がソートされた後、最初の5つの要素は ` top_five_runners +`に保存されます。

任務完了! レースディレクターがやって来て、Pythonの現在のリリースが3.7であるため、フィニッシュラインを通過した37人ごとに無料のジムバッグを手に入れることを決定したことをプログラマに通知します。

この時点で、ランナーのリストが不可逆的に変更されたため、プログラマーは汗をかき始めます。 ランナーの元のリストを完了した順序で回復し、37人ごとに見つける方法はありません。

重要なデータを使用していて、元のデータを復元する必要がある可能性がほとんどない場合、 `+ .sort()`は最適なオプションではありません。 データがコピーである場合、重要でない作業データである場合、取得できるためデータを失うことを誰も気にしない場合、 ` .sort()+`は素晴らしいオプションです。

あるいは、ランナーは `+ sorted()`を使用して同じ ` lambda +`を使用してソートできます。

>>>

>>> runners_by_duration = sorted(runners, key=lambda x: getattr(x, 'duration'))
>>> top_five_runners = runners_by_duration[:5]

`+ sorted()+`を使用したこのシナリオでは、ランナーの元のリストはそのまま残り、上書きされていません。 37人ごとにフィニッシュラインを越える必要があるという即席の要件は、元の値と対話することで実現できます。

>>>

>>> every_thirtyseventh_runners = runners[::37]

`+ every_thirtyseventh_runners `は、 ` runners +`のリストスライス構文のストライドを使用して作成されます。これには、ランナーがフィニッシュラインを横切った元の順序が含まれています。

Pythonでのソート方法:結論

`+ .sort()`と ` sorted()`は、オプションのキーワード引数 ` reverse `と ` key +`の両方で適切に使用すると、必要なソート順を正確に提供できます。

出力とインプレース変更に関しては両方とも非常に異なる特性を持っているので、データを取り消すことができないように上書きする可能性があるため、 `+ .sort()+`を使用するアプリケーション機能またはプログラムを必ず検討してください。

並べ替えの課題を探している熱心なPythonの人のために、並べ替えでより複雑なデータ型を使用してみてください:ネストされたイテラブル。 また、組み込みのオープンソースPythonコードの実装に自由に飛び込み、https://en.wikipedia.org/wiki/Timsort [Timsort]と呼ばれるPythonで使用されるソートアルゴリズムについて読んでください。