たとえば、次のようなネストされたリストがあるとします。
_my_list = [[1, 2, 21], [1, 3], [1, 2]]
_
これに対して関数min()
が呼び出されると:
_min(my_list)
_
受け取った出力は
_[1, 2]
_
なぜ、どのように機能するのですか?それのいくつかのユースケースは何ですか?
Python)内のリスト(および他のシーケンス)は、 辞書的に と比較され、他のパラメーターに基づいていません。
シーケンスオブジェクトは、同じシーケンスタイプの他のオブジェクトと比較できます。比較ではlexicographicalの順序付けを使用します。最初に最初の2つの項目が比較され、それらが異なる場合、これにより比較の結果が決まります。それらが等しい場合は、次の2つの項目が比較されます。
辞書式ソート のウィキペディアのページから
辞書式または辞書式順序(辞書式順序、辞書順、アルファベット順または辞書式(al)積とも呼ばれます)は、単語のアルファベット順がコンポーネント文字のアルファベット順に基づいている方法を一般化したものです。
min
関数は、iterableの最小値を返します。したがって、_[1,2]
_の辞書式値は、そのリストの中で最小です。 _[1,2,21]
_を使用して確認できます
_>>> my_list=[[1,2,21],[1,3],[1,2]]
>>> min(my_list)
[1, 2]
_
min
の場合に何が起こっているのか?-_my_list
_、最初に_[1,2,21]
_および_[1,3]
_を要素ごとに処理します。今からドキュメントから
比較する2つの項目がそれ自体同じタイプのシーケンスの場合、辞書式比較は実行されますrecursively。
したがって、_[1,1,21]
_の値は_[1,3]
_よりも小さくなります。これは、_[1,3]
_の2番目の要素、つまり_3
_が_[1,1,21]
_の2番目の要素の値、つまり_1
_よりも大きい。
_[1,2]
_と_[1,2,21]
_を比較して、ドキュメントから別の参照を追加します
一方のシーケンスが最初のサブシーケンスである場合、短いシーケンスは小さい(小さい)シーケンスです。
_[1,2]
_は_[1,2,21]
_の最初のサブシーケンスです。したがって、全体の_[1,2]
_の値は、_[1,2,21]
_の値よりも小さくなります。したがって、_[1,2]
_が出力として返されます。
これは、 sorted
関数を使用して検証できます
_>>> sorted(my_list)
[[1, 2], [1, 2, 21], [1, 3]]
_
リストに重複する最小要素が含まれている場合最初のものが返されます
_>>> my_list=[[1,2],[1,2]]
>>> min(my_list)
[1, 2]
_
これは、id
関数呼び出しを使用して確認できます
_>>> my_list=[[1,2],[1,2]]
>>> [id(i) for i in my_list]
[140297364849368, 140297364850160]
>>> id(min(my_list))
140297364849368
_
min
の辞書式比較を防ぐために何をする必要がありますか?必要な比較がnot lexicographicの場合、key
引数を使用できます( Padraic で言及)
min
関数には、key
と呼ばれる追加のオプション引数があります。 key
引数は関数を取ります。
オプションのキー引数は、
list.sort()
に使用されるような1つの引数の順序付け関数を指定します。 key引数を指定する場合は、キーワード形式(たとえば、min(a,b,c,key=func)
)である必要があります。
たとえば、長さで最小の要素が必要な場合、関数 len
を使用する必要があります。
_>>> my_list=[[1,2,21],[1,3],[1,2]]
>>> min(my_list,key=len) # Notice the key argument
[1, 3]
_
ご覧のとおり、最初に最も短い要素がここに返されます。
Until Python2
リストが異種type名である場合は、 比較 、
番号を除くさまざまなタイプのオブジェクトは、タイプ名の順に並べられます
したがって、int
とlist
を配置すると、i
はl
よりも小さい値になるため、整数値が最小になります。同様に、_'1'
_は、この両方よりも高い値になります。
_>>> my_list=[[1,1,21],1,'1']
>>> min(my_list)
1
_
Python3以降
ただし、この紛らわしい手法はPython3で削除されました。nowはTypeError
を発生させます。 Python 3.0 の新機能
順序付け比較演算子(_
<
_、_<=
_、_>=
_、_>
_)は、オペランドに意味のある自然な順序付けがない場合、TypeError
例外を発生させます。したがって、_1 < ''
_、_0 > None
_、_len <= len
_などの式は無効になりました。 _None < None
_はTypeError
を返す代わりにFalse
を発生させます。 異種混合リストのソートはもはや意味がありません–すべての要素は互いに比較可能でなければなりません。
_>>> my_list=[[1,1,21],1,'1']
>>> min(my_list)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < list()
_
しかし、それは比較可能なタイプで機能します、例えば
_>>> my_list=[1,2.0]
>>> min(my_list)
1
_
ここで、list
にはfloat
値とint
値が含まれていることがわかります。ただし、float
とint
は比較可能な型であるため、この場合はmin
関数が機能します。
辞書式ソートの簡単な使用例の1つは、ソート可能な namedtuple
クラスを作成することです。
from collections import namedtuple
Time = namedtuple('Time', ['hours', 'minutes', 'seconds'])
t1 = Time(hours=8, minutes=15, seconds=30)
t2 = Time(hours=8, minutes=15, seconds=0)
t3 = Time(hours=8, minutes=30, seconds=30)
t4 = Time(hours=7, minutes=15, seconds=30)
assert min(t1, t2, t3, t4) == t4
assert max(t1, t2, t3, t4) == t3
2つのリストが要素ごとに比較されます
2つのリストのサイズが異なる場合でも、最初の要素から比較を開始して、2つのリストが要素ごとに比較されます。
次に、リストのすべての要素がチェックされ、それらが同じで、短いリストに次の要素がないと仮定します。次に、短いリストは長いリストよりも小さいと宣言されます。
例:
>>> [1,2]<[1,3]
True
>>> [1,2]<[1,2,21]
True
>>> [1,3]<[1,2,21]
False
>>>[1,2,22]<[1,2,21]
False
>>>[1]<[1,2,21]
True
>>>
リストを要素ごとに比較します。
>>> [1,2]<[1,3]
True
>>> [1,2]<[1,2,21]
True
>>>