ふと気になったのでメモ。
環境は macOSX10.15.7 + pyenv + python3.8.3です。
解決方法としては以下の通りでしょうか。
まあロジック自体見直したほうがよいと思います。
-
set()
でうまいことやる - ループでやる
-
__lt__
とか__gt__
を再実装する
双方のリストが同値のとき
>>> a = (100, 200, 300)
>>> b = (100, 200, 300)
>>> a == b
True
これはまあ当然。
リストの要素数が異なるとき
>>> a = (100, 100, 100, 100)
>>> b = (100, 100, 100)
>>> a > b
True
これも当然。
リストの値が異なるとき
>>> a = (100, 100, 100, 100)
>>> b = (200, 100, 100, 100)
>>> a < b
True
>>> a = (100, 100, 100, 100)
>>> b = (100, 100, 100, 200)
>>> a < b
True
値の位置関係は特に関係がなく、想像通りの返り値が得られた。
>>> a = (100, 200, 100, 100)
>>> b = (200, 100, 100, 100)
>>> a < b
True
>>> a = (100, 200, 200, 200)
>>> b = (200, 100, 100, 100)
>>> a < b
True
と思いきや、先頭に近い要素のほうが支配的っぽい。
>>> a = (100, 100, 100, 100)
>>> b = (200, 200, 200)
>>> a < b
True
>>> a = (100, 100, 100, 100)
>>> b = (200, 100, 100)
>>> a < b
True
>>> a = (100, 100, 100, 100)
>>> b = (100, 100, 200)
>>> a < b
True
>>> a = (100, 100, 100, 100)
>>> b = (200, 100)
>>> a < b
True
>>> a = (100, 100, 100, 100)
>>> b = (200, )
>>> a < b
True
要素が少ないことよりも、比較できうる要素同士の結果のほうが優先らしい。
>>> a = (100, 300, 300, 300)
>>> b = (200, )
>>>
>>> a < b
True
なんでやねん
ロジックどうなってるの?
調べてみたところ、リストやタプルに対して比較演算を行ったときは、下記のような処理になっているみたいです。
間違っていれば指摘(あるいは編集リクエスト)いただけると嬉しいです。
- 要素を双方からひとつ取り出す
- 値を比較する
- 同値の場合: 1に戻る
- 同値ではない場合: 3に進む
- どちらかが空の場合: 空のほうにマイナス無限大を挿入し、3に進む
- 両方が空の場合: 双方にマイナス無限大を挿入し(?)、3に進む
- 比較できない型同士の場合: TypeErrorを送出する
- 演算子に対応した真偽値を返却し、処理を終了する
ちなみに公式ドキュメントを見てみてもフワッとしか書かれておらず、やらないほうがいいっぽい雰囲気を感じます。
https://docs.python.org/ja/3/reference/expressions.html#comparisons
比較の結果が等価となる2つのコレクションは、同じ型、同じ長さ、対応する要素どうしの比較の結果が等価でなければなりません (例えば、 [1,2] == (1,2) は型が同じでないので偽です)。
順序比較をサポートしているコレクションの順序は、最初の等価でない要素の順序と同じになります (例えば、 [1,2,x] <= [1,2,y] は x <= y と同じ値になります)。 対応する要素が存在しない場合、短い方のコレクションの方が先の順序となります (例えば、 [1,2] < [1,2,3] は真です)。