すべてのタイプを比較し、論理値を検出し、文字列を変換し、すべてのデータタイプで数学演算を実行できます。
論理値の検出
オブジェクトまたはそのクラスがbool()メソッドを再定義して返すFalse
か、オブジェクトがlen()メソッドを定義してゼロを返す場合を除き、任意のデータ型またはオブジェクトの論理値をテストでき、デフォルトでは真理値と見なされます。
以下は、ロジック検出中に誤った値と見なされるオブジェクトです:
。false値として定義された定数:None 和 False
。任意の数値型のゼロ:0,0.0,0j,Decimal(0),Fraction(0,1)
。空のシーケンスと多項セット:'',(),{},set(),range(0)
ブール演算
ブール演算には、 and、or、not
not>および>または優先順位が含まれます
計算 | 結果 | 注釈 |
---|---|---|
xまたはy | xがfalseの場合は、yを返し、そうでない場合はxを返します。 | または短絡演算子の場合、2番目のパラメーターは、最初のパラメーターがfalse値の場合にのみ評価されます。 |
xとy | xがfalseの場合は、xを返し、そうでない場合はyを返します。 | また、短絡演算子です。2番目のパラメーターは、最初のパラメーターがtrueの場合にのみ評価されます。 |
xではない | xがfalseの場合はTrueを返し、そうでない場合はFalseを返します。 | 優先順位は非ブール演算子の優先順位よりも低いため、次のように not a == b 解釈されnot (a==b) 、a == not b 構文エラーが発生します。 |
比較演算
Pythonには同じ優先順位の8つの比較演算子がありますが、すべてブール演算よりも優先順位が高く、比較演算子は任意に直列に接続できます。たとえば、前者のyは1回だけ評価され、後者は2回評価さx<y<=z
れるというx< y and y <=z
違いに相当し ます。同じ点は、x <yの結果がfalseの場合はzが評価されないということです。
8つの比較演算子は次のとおりです。
オペレーター | 意味 |
---|---|
< | 未満 |
<= | 以下 |
>> | 以上 |
> = | 以上以上 |
== | 等しい |
!= | 等しくない |
です | オブジェクトID |
ではありません | ネガティブオブジェクトの識別 |
比較操作で注意すべき点
。比較すると、異なる数と異なるタイプのオブジェクトが等しくなることはありません
。関数タイプは、簡略化されたフォーム比較のみをサポートします
。<、<=、>、> =複素数と他の数値タイプを比較する場合、2つのオブジェクトのタイプが異なり、比較できない場合、または順序が定義されていないその他の状況では、上記はすべてTypeErroe
例外を生成します。
.eq()メソッドが定義されていない限り、異なる識別クラスのインスタンスは等しくありません
クラスインスタンスがない限り、同じクラス又は他のインスタンスまたは他のタイプのオブジェクトでソートすることができない こと()、ル()、GT()は、GEは、()が定義されています
。 is
また is not
、カスタマイズすることはできず、例外をスローせずに任意の2つのオブジェクトに適用できます。
。in
そして not in
、上記の8種類の比較演算子は同じ優先順位を持ちますが、Iterable(iterables)をサポートするか、Type()メソッドを含む実装のみをサポートします。
数値演算
複素数型を除くすべての数値型は、以下の演算をサポートしています。すべての数値演算の優先度は、比較演算の優先度よりも高くなっています。以下は、優先度の昇順で並べられています。
計算 | 意味 |
---|---|
+ | 2つの数値の合計 |
- | 2つの数値の違い |
$ \ times $ | 2つの数の積 |
/ | 2つの数値を除算すると、結果が商に返されます。 |
// | 2つの数値を除算すると、結果は商を返します |
% | 2つの数値を割り、余りを取ります |
-バツ | x否定 |
+ x | x正 |
abs(x) | xの絶対値 |
int(x) | xを整数に変換する |
float(x) | xを浮動小数点に変換します |
complex(re、im) | 実数部reと虚数部imの複素数、imのデフォルトは0です。 |
c.conjugate() | 複素数cの共役 |
divmod(x、y) | x // yx%yを実行して、xをyで割った後の商と余りを取得します。 |
パウ(x、y) | xのy乗 |
x ** y | また、xをyの累乗で表します |
invmod(x,y) | 对x模y取反 |
数字运算注意点:
. / 除法运算返回的永远是一个浮点数
.// 整除结果值是一个整数,但结果的类型不一定是int。 运算结果永远向负无穷方向舍入, 1//2 为0, (-1)//2 为-1,1//(-2)为-1,(-1)//(-2)为0。
. % 不能用于复数
. int() 若从浮点数转换为整数会被舍入或被截断,原因在前面文章数字类型中提到过,因为二进制浮点数问题
数字类型还能进行数学函数运算,具体会在后面math和cmath模块讲到。
整数类型按位运算
按位运算只对整数有意义,按位运算优先级低于数字运算,高于比较运算,但一元运算~
与其它一元算术运算符优先级相同。
运算 | 含义 | 说明 | |
---|---|---|---|
x\ | y | x和y按位或 | |
x^y | x和y按位异或 | ||
x&y | x和y按位与 | ||
x<<n | x左移n位 | 负的移位会引发ValueError,左移n位等价于不带溢出检测的乘以pow(2,n) | |
x>>n | x右移n位 | 负的移位同样会引发ValueErroe,右移n位等价于不带溢出检测的除以pow(2,n) | |
~x | x按位取反 |
数字类型的哈希运算
不同数字类型的两个数,要做== 比较运算时,必须转成哈希值,即hash(x)==hash(y)。为便于在各种数字类型上实现并保证效率,Python对数字类型的哈希运算是基于任意有理数定义统一的数学函数,本质上hash()是通过以一个固定质数P进行P降模。P的值在 Python 中可以 sys.hash_info
的 modulus
属性的形式被访问。
CPython implementation detail: 所用质数设定,在 C long 为 32 位的机器上 P = 2**31 - 1
而在 C long 为 64 位的机器上 P = 2**61 - 1
运算规则如下:
- 如果
x = m / n
是一个非负比例数,且n
不能被P
整除,则定义hash(x)
为m * invmod(n, P) % P
。 - 如果
x = m / n
是一个非负比例数,且n
能被P
整除(但m
不能)则n
不能对P
降模,以上规则不适用;在此情况下则定义hash(x)
为常数值sys.hash_info.inf
。 - 如果
x = m / n
是一个负比例数,则定义hash(x)
为-hash(-x)
。 如果结果哈希值为-1
则将其替换为-2
。 - 特定值
sys.hash_info.inf
,-sys.hash_info.inf
和sys.hash_info.nan
被用作正无穷、负无穷和空值(所分别对应的)哈希值。 (所有可哈希的空值都具有相同的哈希值) - 对于一个
complex
值z
,会通过计算hash(z.real) + sys.hash_info.imag * hash(z.imag)
将实部和虚部的哈希值结合起来,并进行降模2**sys.hash_info.width
以使其处于range(-2**(sys.hash_info.width - 1), 2**(sys.hash_info.width - 1))
范围之内。 同样地,如果结果为-1
则将其替换为-2
为了更好的理解运算规则,用代码实现如下:
对分数求哈希值:
>>> import sys,math
>>> def hash_fraction(m,n):
'''计算比例数m/n的哈希值,m和n为整数,n为正数'''
P = sys.hash_info.modulus
#去掉P的公因数,除非m和n互质
while m%P == n%P ==0:
m,n = m//P, n//P
#如果n能被P整除,hash值为固定值
if n % P == 0:
hash_value = sys.hash_info.inf
else:
#如果n不能被P整除,则对P进行降模处理
hash_value = (abs(m)%P)*pow(n,P-2,P)%P
#判断m是否是负数,对负数求hash
if m < 0:
hash_value = -hash_value
if hash_value == -1:
hash_value = -2
return hash_value
对float浮点数类型求哈希值:
>>> def hash_float(x):
#计算浮点数x的哈希值
if math.isnan(x):
return sys.hash_info.nan
elif math.isinf(x):
return sys.hash_info.inf if x > 0 else -sys.hash_info.inf
else:
return hash_fraction(*x.as_integer_ratio())
对复数类型求哈希值:
#计算复数z的哈希值
hash_value = hash_float(z.real) + sys.hash_info.imag * hash_float(z.imag)
M = 2 **(sys.hash_info.width - 1)
hash_value = (hash_value & (M-1)) - (hash_value&M)
if hash_value == -1:
hash_value = -2
return hash_value
Decimal运算实例
Decimal 进行 $+ 、- 、\times 、/$ 运算
>>> data = list(map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split()))
>>> sum (data)
Decimal('19.29')
>>> min(data)
Decimal('0.03')
>>> max(data)
Decimal('9.25')
>>> min(data)
Decimal('0.03')
>>> a,b,c = data[:3]
>>> a * 5
Decimal('6.70')
>>> a * b
Decimal('2.5058')
>>> c % a
Decimal('0.77')
>>> a + b + c
Decimal('6.66')
>>> a - b
Decimal('-0.53')
>>>
当余数运算%应用于Decimal对象时,结果的符号是被除数的符号,而不是除数的符号
>>> -5 % 8
3
>>> Decimal(-5) % Decimal(8)
Decimal('-5')
>>> Decimal(8) % Decimal(-5)
Decimal('3')
同样Decimal也可以进行一些数学函数运算
>>> Decimal(2).sqrt()
Decimal('1.41421')
>>> Decimal(1).exp()
Decimal('2.71828')
>>> Decimal(10).ln
<built-in method ln of decimal.Decimal object at 0x1073b04a8>
>>> Decimal(10).ln()
Decimal('2.30259')
>>> Decimal('10').log10()
Decimal('1')
关于四舍五入,Decimal的quantize()方法可以将数字四舍五入为固定函数
>>> Decimal('7.325').quantize(Decimal('0.01'), rounding=ROUND_DOWN)
Decimal('7.32')
>>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)
Decimal('8')
Fraction运算实例
Fraction同样可以进行$+、-、\times /$ 四则运算和%运算等
>>> from fractions import Fraction
>>> import math
>>> Fraction(2,3) + Fraction(3,5)
Fraction(19, 15)
>>> Fraction(2,3) - Fraction(3,5)
Fraction(1, 15)
>>> Fraction(2,3) * Fraction(3,5)
Fraction(2, 5)
>>> Fraction(2,3) / Fraction(3,5)
Fraction(10, 9)
>>> Fraction(2,3) % Fraction(-3, 5)
Fraction(-8, 15)
>>> Fraction(2,3) % Fraction(3,5)
Fraction(1, 15)
Fraction没有sqrt()、exp()等函数方法。
参考文献: