Python初心者が「Python文法詳解」を読んだメモ #4

# バックナンバー
- [Python初心者が「Python文法詳解」を読んだメモ #1](https://qiita.com/usayomo/items/7024c619c5f72462cb10) 
- [Python初心者が「Python文法詳解」を読んだメモ #2](https://qiita.com/usayomo/items/9c1537678bdde813a273)
- [Python初心者が「Python文法詳解」を読んだメモ #3](https://qiita.com/usayomo/items/57e6156c95e60b3223ca)

```py:is
# 同じオブジェクトなら真を返す
>>> a = b = [1, 2, 3]
>>> a is b
True

# この場合は別のオブジェクトなのでisの結果は偽になる
>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> a is b
False
>>> a == b
True

# isの結果は、オブジェクトのidで判断されている
>>> id(a)
4353816328
>>> id(b)
4353060616

>>> a = b = [1, 2, 3]
>>> id(a)
4353816392
>>> id(b)
4353816392
```

```py:条件演算子（三項演算子）
>>> x = 1
>>> 100 if x == 1 else 200
100

>>> x = 2
>>> 100 if x == 1 else 200
200
>>> x == 1 and 100 or 200   # andとorによる書き換え
200
```

```py:数値演算結果の自動型変換
>>> 1 + 1.0  # 整数 + 浮動小数点数
2.0          # 結果は浮動小数点数
>>> 1 + 1j   # 整数 + 複素数
(1+1j)       # 結果は複素数
```

```py:数値演算メソッド
>>> divmod(20, 6)
(3, 2)  # 除算の商と余りがタプルで返ってくる。便利そう。

>>> pow(3, 4)     # 3 ** 4 と同じ
81
>>> pow(3, 4, 5)  # 3 ** 4 % 5 と同じだが、こちらの方が高速
1
```

```py:int([x,&nbsp;byte])
# 引数がなければ0を返す
>>> int()
0

# 浮動小数点数を渡すと0方向に丸める
>>> int(10.5)
10
>>> int(-10.5)
-10

# 文字列を渡す場合は基数を指定可能
>>> int('100')    # 基数省略時は10進数
100
>>> int('100', 2)
4
>>> int('100', 8)
64
>>> int('100', 10)
100
>>> int('100', 16)
256

# 基数を0とすると、整数リテラルとして変換する
>>> int('100', 0)
100
>>> int('0b100', 0)
4
>>> int('0o100', 0)
64
>>> int('0x100', 0)
256

# Unicode文字データベース上数字とされている文字であれば変換可能
>>> int('V', 32)
31
>>> int('１００', 2)
4
```

```py:バイナリ→整数オブジェクト
>>> int.from_bytes(b'\x00\xff', byteorder = 'big')  # クラスメソッドなので、int型のメソッドとして呼び出す
255
# signed = True とするとバイト列を2の補数による符号付き整数として変換する 
>>> int.from_bytes(b'\xfe\xff\xff\xff', byteorder = 'little', signed=True)
-2
```

```py:整数型オブジェクトのメソッド
# 整数値のバイト列を取得
>>> (255).to_bytes(2, byteorder = 'big')
b'\x00\xff'
# 2の補数として変換
>>> (-2).to_bytes(4, 'little', signed = True)
b'\xfe\xff\xff\xff'

# 数値を2進数に変換するために必要なビット数を返す（符号ビットは含まれない）
>>> (100000000).bit_length()
27
```

```py:論理値型
# 整数型の派生型で、実のところTrueは整数の1だしFalseは整数の0
>>> int(True)
1
>>> int(False)
0

# 普通の整数と同じ演算もできる
>>> True + False
1
>>> True * False
0
>>> False - 1
-1
>>> True + 1
2
>>> True / 2
0.5
```

```py:論理値オブジェクト
# 論理値オブジェクトはbool型のオブジェクト
# TrueオブジェクトとFalseオブジェクトは常にそれぞれ1つしか存在しない
>>> bool(0)
False
>>> bool(1)
True
>>> bool([100])
True
>>> bool([])
False
>>> bool()
False
```

```py:ビット反転
# ~xは-1*(x+1)となる整数値を返す（Python内部的にはビット演算しない）
>>> ~5
-6
>>> ~(-6)
5
>>> '{:08b}'.format(5 & 0xff)
'00000101'
>>> '{:08b}'.format(-6 & 0xff)
'11111010'
```

```py:浮動小数点数演算における無限大・非数
# 浮動小数点数の値が有効な範囲より大きい場合
>>> 1e200 * 1e200
inf  # 無限大はinfと表示される
>>> -1e200 * 1e200
-inf

# 無限大の値との演算などで、結果が非数（Not A Number:NaN）となる場合
>>> 0 * 1e1000
nan

# 値がinf, nanの浮動小数点数は、float()メソッドで作成する
>>> float('nan')        # 非数
nan
>>> float('inf')        # 無限大
inf
>>> float('-inf')       # 負の無限大
-inf
>>> float('infinity')   # 'infinity'も無限大
inf
```

```py:浮動小数点数オブジェクトのメソッド
# 比率がオブジェクトの値と同じになる2つの整数値のタプルを返す。2つ目の値は常に正の値となる。
>>> (0.5).as_integer_ratio()
(1, 2)
>>> (-2.5).as_integer_ratio()
(-5, 2)

# inf, nanに対しては以下例外を送出
>>> float('inf').as_integer_ratio()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: Cannot pass infinity to float.as_integer_ratio.

>>> float('nan').as_integer_ratio()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Cannot pass NaN to float.as_integer_ratio.


# オブジェクトの値を16進数形式の文字列で出力
# [sign]['0x']integer['.'fraction]['p'exponent] 形式で作成
>>> 1.0.hex()
'0x1.0000000000000p+0'


# 値の小数点以下がゼロで、infやnanでない整数値ならばTrueを返す
>>> (-2.0).is_integer()
True
>>> (3.2).is_integer()
False
>>> float('inf').is_integer()
False
>>> float('nan').is_integer()
False
```

```py:10進浮動小数点数
# 浮動小数点数での計算は、一般に誤差が発生する
>>> 0.3 - 0.2
0.09999999999999998

# Pythonでは、10進数の浮動小数点数演算のためにdecimalモジュールが提供されている
# float型の演算とは違い、全てソフトウェアでの計算となるためパフォーマンスは低下する
>>> import decimal
>>> print(decimal.Decimal('0.3') - decimal.Decimal('0.2'))
0.1

# inf, nan
>>> from decimal import Decimal
>>> Decimal('inf')
Decimal('Infinity')

>>> Decimal('nan') + 1   # nanとの演算は結果もnanとなるが、
Decimal('NaN')
>>> Decimal('sNaN') + 1  # シグナリングNaNという特殊値を使うと例外発生させることができる
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
```