pythonを使い始めてもうすぐ1年。
最近「|」(縦棒?バーティカルバー?)を使った処理を覚えたので備忘録としてシェアします。
※ ちなみにネットで調べても「ビット単位論理和」としか出てこない為、もしかすると正規の使い方ではないかも知れませんがあしからず。
この処理は「条件Aと条件Bがある場合、両方とも評価して条件を満たしていれば両方とも採用する(もちろん片方だけでも)」というものです。
以下サンプルコード
list01 = list(range(3)) [0,1,2]
# 1. "a"の値には1より小さい数を、"b"の値には1より大きい数を設定する
print({"a": i for i in list01 if i < 1} | {"b": n for n in list01 if n > 1})
# {'a': 0, 'b': 2}
# 2. "a"の値には0より小さい数を、"b"の値には1より大きい数を設定する
print({"a": i for i in list01 if i < 0} | {"b": n for n in list01 if n > 1})
# {'b': 2} aの要素がなくなっている
# 3. "a"の値には1より小さい数を、"b"の値には2より大きい数を設定する
print({"a": i for i in list01 if i < 1} | {"b": n for n in list01 if n > 2})
# {'a': 0} bの要素がなくなっている
如何でしょう?ビット演算でも論理和でもないですよね?但しこれには条件があり、
- 古いバージョンでは使えない(var.3.9はダメでした。検証したのはver.3.12)
- dictじゃないと評価できない
- valueに書く条件はforから始める(ifやlist(filter)を使うとNoneや[]が残ってしまう)
私が検証した限りは以上の条件があります。
ここまでですと「いつ使うの?」という感想になりそうですが、この度私が使ったケースは「groupby」を使ったもので、以下のような感じです。
from itertools import groupby
list02 = [0, 0, 0, 1, 1, 2]
# 1. 値が0と1のリストを作り、keyをラベルとして使う
print(
{k: list(n) for k, n in groupby(filter(lambda x: x == 0, list02))}
| {k: list(n) for k, n in groupby(filter(lambda x: x == 1, list02))}
)
# {0: [0, 0, 0], 1: [1, 1]}
# 2. 1と同じ処理で、値が0と3のリストを作り、keyをラベルとして使う
print(
{k: list(n) for k, n in groupby(filter(lambda x: x == 0, list02))}
| {k: list(n) for k, n in groupby(filter(lambda x: x == 3, list02))}
)
# {0: [0, 0, 0]} 3はリストに無い為、辞書に追加されない
以上、groupbyだとなかなか使い道があるように思えるのですが、如何でしょうか。
頻繁に使う事はないと思いますが、覚えておくと役に立つ場面があるように思えます。
コメント