Skip to content

Python 演算子#

Python の演算子は大きく以下5つに分類される

  1. 算術演算子
  2. 代入演算子
  3. 比較演算子
  4. 論理演算子
  5. ビット演算子

また、関数形式、特殊メソッドでの演算子もサポートされています。

算術演算子#

演算子 説明 結果
+ 加算 1 + 1 2
- 減算 3 - 2 1
* 乗算 2 * 2 4
** べき乗 2 ** 3 8
/ 除算 4 / 3 1.333...
// 除算(切り捨て) 7//3 2
% 剰余(割った余り) 10 % 1 1

Info

  • 演算子の役割はオペランド(被演算子)のデータ型によって変化します。
  • Python では原則、型をそろえてから演算します。
  • 商と剰余をまとめて得るなら divmod 関数も利用できます。

浮動小数点数の演算#

  • 浮動小数点数を含んだ演算では意図した結果が得られないことがある。
  • 例えば、print(0.2 * 3)の結果は0.6000000000000001となり、これは、Pytnonが内部的に数値を(10進数ではなく)2進数で演算しているため生じる誤差
  • もちろん、0.2 * 3 == 0.6 の等式の結果はFalseになる
  • 厳密な結果を要求するような状況では、Decimal型を利用する(Decimal型は10進数の浮動小数点をサポート)
import decimal

d1 = decimal.Decimal('0.2')
d2 = decimal.Decimal('3')
d3 = decimal.Decimal('0.6')

print(d1 * d2)
print(d1 * d2 == d3)

Warnig

  • Decimal 型の値を生成するときは、リテラルの段階で誤差が発生してしまうため、浮動小数点数リテラルを渡してはいけない。
  • ※ リテラル = 数値や文字列を人間が分かる表記でべた書きしたもの
# 悪い例    
d1 = decimal.Decimal(0.2)

代入演算子#

代入演算子は、左辺で指定した変数に対して演算下結果を変数に格納します。 代入演算子には、算術演算子やビット演算子などを合わせた機能を提供する複合代入演算子も含まれます。

演算子 概要 x の値
= 左辺に右辺の値を代入 x = 1 1
+= 左辺と右辺を加算し、左辺に代入 x = 1
x += 2
3
-= 左辺から右辺を減算し、左辺に代入 x = 3
x -= 1
3
*= 左辺と右辺を乗算し、左辺に代入 x = 3
x *= 3
9
/= 左辺を右辺で除算し、左辺に代入 x = 5
x /= 2
2.5
//= 左辺を右辺で除算し、(整数部を)左辺に代入 x = 5
x //= 2
2
%= 左辺を右辺で除算した余りを、左辺に代入 x = 5
x %= 2
1
**= 左辺を右辺でべき乗し、左辺に代入 x = 5
x **= 2
25
&= 左辺と右辺をビット論理積し、左辺に代入 x = 10
x &= 2
2
^= 左辺と右辺をビット排他論理和し、左辺に代入 x = 10
x ^= 2
8
|= 左辺と右辺をビット論理和し、左辺に代入 x = 10
x |= 2
10
>>= 左辺を右辺の値だけ右シフトし、左辺に代入 x = 10
x >>= 2
2
<<= 左辺を右辺の値だけ左シフトし、左辺に代入 x = 10
x <<= 2
40

数値のインクリメント / デクリメント#

他の言語での数値のインクリメント / デクリメント は ++ / -- と記述しますが、 Python では以下のように記述します。

  • インクリメント+=
  • デクリメント-=

:=(セイウチ)演算子(Python 3.8~)#

  • 変数への代入と変数の使用を同時に実行できる演算子です。
  • What's New In Python 3.8 - 代入式

    大きな構文の一部として、変数に値を割り当てる新しい構文 := が追加されました。 この構文は セイウチの目と牙 に似ているため、「セイウチ演算子」の愛称で知られています。 以下の例では、代入式により len() 関数を二重に呼びだすことを回避しています:

    if (n := len(a)) > 10:
        print(f"List is too long ({n} elements, expected <= 10)")
    

比較演算子#

演算子 説明 result
< 左辺が右辺より小さい場合に True 5 < 10 True
> 左辺右辺より大きい場合に True 5 > 10 False
== 左辺が右辺と等しい場合に True 5 == 5 True
<= 左辺が右辺以下の場合に True 5 <= 10 True
>= 左辺が右辺以上の場合に True 5 >= 10 False
!= 左辺と右辺が等しくない場合に True 5 != 10 True
is [not] 左辺と右辺のオブジェクトが等しい場合に True [1, 2] is [1, 2] False
[not] in 左辺が右辺に含まれている場合にTrue 3 in [1, 2, 3] True

異なる型での比較#

異なる型同士では基本エラーだが、「==」「!=」演算子は異なる型同士でも比較できます。 一般的にはFalseを返します。

print(1 == '1')
print(False == None)

ただし、数値型同士の比較だけは例外で、int型とfloat型とは数値として正しく等価/大小を判定できます。

print(1==1.0) # True
print(1.5 < 1) # False

また、文字列/数値同士と、データ型での比較は意図しない結果となる可能性があります。

print(15 < 131) # True
print('15' < '131') # False

リストの比較#

先頭から要素を比較していき、最初に異なる要素が見つかった場合に、その大小でリスト全体の大小を決定します。

data1 = [1, 2, 3]
data2 = [1, 5]
data3 = [1, 2]

print(data1 < data2) # True
print(data1 < data3) # False

浮動小数点数の比較#

浮動小数点数は内部的には2進数として扱われ、その比較式は Python では False となります。 正確な判定には、浮動小数点数を比較するには以下の方法を用います。

  1. Decimal 型
TOLERANCE = 0.00001
x = 0.2 * 3
y = 0.6
print(abs(x - y) < TOLERANCE)
  1. 端数の切り捨てによる比較

端数の切り捨てによる比較 には isclose 関数を用います。

import math

print(math.isclose(0.2 * 3, 0.6))

isclose 関数は厳密に等しくなくとも近似値であれば True を返します

  • math --- 数学関数

    値 a と b が互いに近い場合 True を、そうでない場合は False を返します。
    2値が近いと見なされるかどうかは与えられた絶対または相対許容差により決定されます。
    rel_tol は相対許容差、すなわち a と b の絶対値の大きい方に対する a と b の許容される最大の差です。 例えば許容差を 5% に設定する場合 rel_tol=0.05 を渡します。 デフォルトの許容差は 1e-09 で、2値が9桁同じことを保証します。 rel_tol は0より大きくなければなりません。
    abs_tol は最小の絶対許容差です。0に近い値を比較するのに有用です。abs_tol は0以上でなければなりません。

同一性と同値性#

比較演算子を利用する上で、同一性(Identity)と同値性(Equivalence)を区別することは重要です。 * 同一性 : 参照値が同じオブジェクトを参照していること (同じオブジェクトか =格納先が等しいか) * 同値性 : オブジェクトが同じ値を持っていること(値として等しいか =意味的な値の確認)

price1 = [100, 200, 300]
price2 = [100, 200, 300]

# 「==」は同値性を確認する
print(price1 == price2) # True
# is演算子はオブジェクトの同一性を確認する
print(price1 is price2) # False

イミュータブル型の同一性#

文字列はイミュータブルであり、Pythonではメモリを節約するため同じ値を利用しています。 そのため、以下例の is 演算子の結果は False ではなく True となります。

sushi1 = 'サーモン'
sushi2 = 'サーモン'
print(sushi1 == sushi2) # True
print(sushi1 is sushi2) # True

None値の比較#

ある式が None であるかを判定するには == 演算子ではなく、is 演算子を利用します。 (== 演算子の挙動は左オペランドの型によって変化する可能性があるためです。)

条件演算子#

条件演算子は、指定された条件式の真偽に応じて、対応する式の値を返します。

score = 60
print('合格' if score >= 50 else '不合格...')

論理演算子#

論理演算子は、複数の条件式(または真偽値)を論理的に結合し、その結果をTrue / Falseとして返します。 なお、^演算子はビット演算子に分類されるべき演算子ですが、論理積・論理和と比較したほうが理解が容易なため、以下でまとめています。

演算子 説明 判定結果
and 論理積。左右の式がともに True の場合に True x and y False
or 論理和。左右のいずれかが True の場合に True x or y True
^ 排他的論理和。左右のいずれかが True かつ、ともに True でない場合に True x ^ y True
not 否定。式が True の場合は False。式が False の場合は True not x False

ショートカット演算(短絡演算)#

論理積 / 論理和演算では、ある条件のもとでは、左式だけが評価されて右式が評価されない場合がある。このような演算のことをショートカット演算、あるいは短絡演算といいます。

Note

論理積/論理和演算子には、もう一つ「&」「|」演算子があります。 判定のルールは「and」「or」演算子と同じですが、ショートカットの性質を持たない点がことなります。

論理積/論理和演算子のこの性質を利用することで、以下のようなコードを表現できる。しかし、コードが本来の論理演算を意図して書かれているものか、条件分岐を目的としたものであるかわかりにくくなるため一部の例外を除いて利用すべきではない。

x = 1
if x != 2:
  print('実行されました。')
x == 2 or print('実行されました。')

ショートカット演算子の実例#

Pythonの論理演算子は、左式/右式と最後に評価された値を返す、という性質があります。 その性質とショートカット演算のルールによって、左式で評価を打ち切った場合には左式の値が、 さもなければ右式の値が返されます。

print(True and 1)
print(False and 2)
print(True or 3)
print(False or 4)

前述の性質を利用し、値を返さない(または失敗する)可能性がある処理に対し、既定値を渡すようなコードも簡単に表せます。 例えばb、以下は、hoge関数が値を返さなかった、またはFalseである場合に、既定値として「default」を返す例です。

print(hoge() or 'default')

Note

ただし、空文字列やゼロ値など、Falseと判定されるような値そのものに意味がある場合には、 本文のようなイディオムは利用できません。空文字列やゼロなどの値が既定値(ここでは「default」) によって上書きされてしまうからです。そのような場合には、以下のように条件演算子を利用してください

result = hoge()
print('default' if result is None else result)
これによって、hoge関数の戻り値がない(None)場合にだけ、既定値が適用されます。

比較演算子の連結#

たとえば、x が50~100の範囲を50 <= x <= 100のように比較演算子を連結することで表現できる。式xが一度しか評価されないため、実行効率に優れる。

ビット演算子#

ビット演算を行うための演算子です。ビット演算とは、整数を2進数で表したときの格桁(ビット単位)を論理計算する演算のこと。ビット演算では、与えられた整数を2進数に変換した上で、それぞれの桁について、論理演算を実施します。

演算子の優先順位と結合則#

優先順位#

演算子には優先順位があります。異なる演算子の処理順序を決めるのが優先順位です。

結合則#

同じ優先順位の演算子を処理する順序を決めるのが結合則です。以下、基本ルール * 左から右への演算が基本 * べき乗演算子(**)と代入演算子は右結合。例えば、2 ** 2 ** 32 ** (2 ** 3)の式は同じ意味です。

関数形式の演算子#

  • operator --- 関数形式の標準演算子

  • 演算子から関数への対応表

    演算

    操作

    関数

    加算

    a + b

    add(a, b)

    結合

    seq1 + seq2

    concat(seq1, seq2)

    包含判定

    obj in seq

    contains(seq, obj)

    除算

    a / b

    truediv(a, b)

    除算

    a // b

    floordiv(a, b)

    ビット単位論理積

    a & b

    and_(a, b)

    ビット単位排他的論理和

    a ^ b

    xor(a, b)

    ビット単位反転

    ~ a

    invert(a)

    ビット単位論理和

    a | b

    or_(a, b)

    冪乗

    a * b

    pow(a, b)

    同一性

    a is b

    is_(a, b)

    同一性

    a is not b

    is_not(a, b)

    インデクス指定の代入

    obj[k] = v

    setitem(obj, k, v)

    インデクス指定の削除

    del obj[k]

    delitem(obj, k)

    インデクス指定

    obj[k]

    getitem(obj, k)

    左シフト

    a << b

    lshift(a, b)

    剰余

    a % b

    mod(a, b)

    乗算

    a b

    mul(a, b)

    行列の乗算

    a @ b

    matmul(a, b)

    (算術) 負

    - a

    neg(a)

    (論理) 否

    not a

    not_(a)

    + a

    pos(a)

    右シフト

    a >> b

    rshift(a, b)

    スライス指定の代入

    seq[i:j] = values

    setitem(seq, slice(i, j), values)

    スライス指定の削除

    del seq[i:j]

    delitem(seq, slice(i, j))

    スライス指定

    seq[i:j]

    getitem(seq, slice(i, j))

    文字列書式化

    s % obj

    mod(s, obj)

    減算

    a - b

    sub(a, b)

    真理値判定

    obj

    truth(obj)

    順序付け

    a < b

    lt(a, b)

    順序付け

    a <= b

    le(a, b)

    等価性

    a == b

    eq(a, b)

    不等性

    a != b

    ne(a, b)

    順序付け

    a >= b

    ge(a, b)

    順序付け

    a > b

    gt(a, b)