Pythonの組み込み関数69個を制覇する 第1回 a～b 

Pythonでは、非常に多くの組み込み関数(Built-in Functions)が用意されており、ライブラリをimportせずとも様々な処理を行うことができます。
基本に立ち返って、組み込み関数の使い方を整理して行きたいと思います。
尚、実行例はWindows Subsystem for LinuxのUbuntu18.04にインストールしたPython3.7.1で作成しています。

[Pythonの組み込み関数69個を制覇する 第2回 c～d](https://qiita.com/ichi_taro3/items/696b355d79d01a810381)
[Pythonの組み込み関数69個を制覇する 第3回 e～g](https://qiita.com/ichi_taro3/items/c866b7124415464e8ef1)
[Pythonの組み込み関数69個を制覇する 第4回 h～i](https://qiita.com/ichi_taro3/items/ee55257338b32c073bad)
[Pythonの組み込み関数69個を制覇する 第5回 l～o](https://qiita.com/ichi_taro3/items/f2cb744a879a084e49af)
[Pythonの組み込み関数69個を制覇する 第6回 p～r](https://qiita.com/ichi_taro3/items/2c2b399b762f5800fe82)


## 組み込み関数の個数は?
[公式ドキュメント](https://docs.python.org/ja/3/library/functions.html) の表では、Python3.7.2では69個の組み込み関数が挙げられています。

これらの関数は、\_\_builtins__に設定されています。

```Python3
>>> print(list(name for name in vars(__builtins__)))
['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__build_class__', '__import__', 'abs', 'all', 'any', 'ascii', 'bin', 'breakpoint', 'callable', 'chr', 'compile', 'delattr', 'dir', 'divmod', 'eval', 'exec', 'format', 'getattr', 'globals', 'hasattr', 'hash', 'hex', 'id', 'input', 'isinstance', 'issubclass', 'iter', 'len', 'locals', 'max', 'min', 'next', 'oct', 'ord', 'pow', 'print', 'repr', 'round', 'setattr', 'sorted', 'sum', 'vars', 'None', 'Ellipsis', 'NotImplemented', 'False', 'True', 'bool', 'memoryview', 'bytearray', 'bytes', 'classmethod', 'complex', 'dict', 'enumerate', 'filter', 'float', 'frozenset', 'property', 'int', 'list', 'map', 'object', 'range', 'reversed', 'set', 'slice', 'staticmethod', 'str', 'super', 'tuple', 'type', 'zip', '__debug__', 'BaseException', 'Exception', 'TypeError', 'StopAsyncIteration', 'StopIteration', 'GeneratorExit', 'SystemExit', 'KeyboardInterrupt', 'ImportError', 'ModuleNotFoundError', 'OSError', 'EnvironmentError', 'IOError', 'EOFError', 'RuntimeError', 'RecursionError', 'NotImplementedError', 'NameError', 'UnboundLocalError', 'AttributeError', 'SyntaxError', 'IndentationError', 'TabError', 'LookupError', 'IndexError', 'KeyError', 'ValueError', 'UnicodeError', 'UnicodeEncodeError', 'UnicodeDecodeError', 'UnicodeTranslateError', 'AssertionError', 'ArithmeticError', 'FloatingPointError', 'OverflowError', 'ZeroDivisionError', 'SystemError', 'ReferenceError', 'MemoryError', 'BufferError', 'Warning', 'UserWarning', 'DeprecationWarning', 'PendingDeprecationWarning', 'SyntaxWarning', 'RuntimeWarning', 'FutureWarning', 'ImportWarning', 'UnicodeWarning', 'BytesWarning', 'ResourceWarning', 'ConnectionError', 'BlockingIOError', 'BrokenPipeError', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionRefusedError', 'ConnectionResetError', 'FileExistsError', 'FileNotFoundError', 'IsADirectoryError', 'NotADirectoryError', 'InterruptedError', 'PermissionError', 'ProcessLookupError', 'TimeoutError', 'open', 'quit', 'exit', 'copyright', 'credits', 'license', 'help', '_']
```
公式ドキュメントにかかれているものよりもたくさん出てきました。

これらのうち、大文字始まりのものは、None, Ellipsis, True, Falseと、BaseExceptionおよびそれらを継承する例外系のクラスのようです。[^1]
[^1]: コンソールでhelp(\_\_builtins__)とするとオブジェクトの継承関係がツリーで表示されます。
ということは、小文字始まりだけ抽出すれば、ドキュメントに書かれているものが取り出せそうです。

```Python3
>>> print(list(name for name in vars(__builtins__)
...     if (name[0].islower() and name not in ('quit', 'exit', 'copyright', 'credits', 'license',)) or name=='__import__'))
['__import__', 'abs', 'all', 'any', 'ascii', 'bin', 'breakpoint', 'callable', 'chr', 'compile', 'delattr', 'dir', 'divmod', 'eval', 'exec', 'format', 'getattr', 'globals', 'hasattr', 'hash', 'hex', 'id', 'input', 'isinstance', 'issubclass', 'iter', 'len', 'locals', 'max', 'min', 'next', 'oct', 'ord', 'pow', 'print', 'repr', 'round', 'setattr', 'sorted', 'sum', 'vars', 'bool', 'memoryview', 'bytearray', 'bytes', 'classmethod', 'complex', 'dict', 'enumerate', 'filter', 'float', 'frozenset', 'property', 'int', 'list', 'map', 'object', 'range', 'reversed', 'set', 'slice', 'staticmethod', 'str', 'super', 'tuple', 'type', 'zip', 'open', 'help']
>>> print(len(list(name for name in vars(__builtins__)
...     if (name[0].islower() and name not in ('quit', 'exit', 'copyright', 'credits', 'license',)) or name=='__import__')))
69
```

小文字始まりのものと、`__import__`が組み込み関数として扱われているようです。
`'quit', 'exit', 'copyright', 'credits', 'license'`が組み込み関数とされていないのは、プログラムの終了や著作権、クレジット、ライセンスと、何らかのデータを処理する他の関数と性質が異なるからでしょうか？

このあたりの厳密な定義や取得方法はよくわからなかったので、知っている方がいれば教えていただきたいです。

## 関数の使い方
ここからは、各関数の使い方を記述していきます。詳細な使い方は他の記事に譲るとして、ここでは簡単な使用例を中心に掲載していきます。

(2019/01/31 追記)
コメントで指摘いただきました。公式ドキュメントで「組み込み関数」と呼ばれているものの中には、実際には関数ではなくコンストラクタに分類されるものがあります。
完全なリストは提示しませんが、例えば`int()` `float()` `str()` `bytes()` `complex()` などはコンストラクタであり、それぞれのクラスの新たなインスタンスを生成して返却します。
これ以降の記事中では特に関数かコンストラクタかの分類は明記しませんが、興味がある方は意識してみてください。

#### abs()
数値の絶対値を返却する関数です。
引数には整数か浮動小数を渡します。また複素数も渡すことができるようです。

```Python3
>>> # int: 整数型
... abs(1)
1
>>> abs(-1)
1
>>> # float: 浮動小数型
... abs(-3.4)
3.4
>>> # complex: 複素数型
... abs(3+2j)
3.605551275463989
```

#### all()
引数に渡した要素がすべて真であればTrueを返します。それ以外はFalseです。
引数はiterableです。つまり、ループできるものなら渡せると考えればよいでしょう。

```Python3
>>> # 空ならばTrue
... all([])
True
>>> # list
... all([1,2,3])
True
>>> # list: 0が偽になるのでFalse
... all([1,3,0])
False
>>> # strも渡せる
... all('Ramen')
True
>>> # mapオブジェクトも使える
... all(map(lambda x:x==42, [3,5,1,42]))
False
>>> all([True, True, True])
True
```
if文の条件をandでつなげて書くのを、以下のように書き換えることもできます。[^2]

[^2]: 厳密には、この書換えは全く同じ動きをするわけではありません。例えば、`is_hoge('hoge')` がFalseとして評価された場合、and 演算子では短絡評価が行われるためこれ以降の関数`is_fuga()`, `is_piyo()`が実行されません。一方、`all()`の引数にリストで各関数を渡した場合、allが実行される前に引数の評価が行われるので、`is_hoge()`の結果と関係なく３つの関数が全て実行されることになります。ということは、もし、`is_fuga()`がTrue/Falseを返却する以外にデータを変更する仕事をしていたり、`is_piyo()`がエラーを起こすような実装になっていたりすると、明確に挙動が変わることになりますね。


```Python3
>>> if is_hoge('hoge') and is_fuga('fuga') and is_piyo('piyo'):
...     print('hogefugapiyo')
...
hogefugapiyo
>>> # ↑ をこんなふうに書くこともできる
... if all([is_hoge('hoge'), is_fuga('fuga'), is_piyo('piyo')]):
...     print('hogefugapiyo')
...
hogefugapiyo

```


#### any()
all()と同じく引数にはiterableを渡しますが、評価の仕方が異なります。
any()はOR条件で、引数のiterableのどれか一要素でも真ならTrue, すべて偽の場合にFalseになります。
all()は全て真のときにTrueを返すというAND条件の関数なので違いに注意してください。

```Python3
>>> # 空のときはFalse
... any([])
False
>>> # list
... any([1,2,3])
True
>>> # list: 1と3が真になるのでTrue
... any([1,3,0])
True
>>> # strも渡せる
... any('Tsukemen')
True
>>> # mapオブジェクトも使える
... any(map(lambda x:x==42, [3,5,1,42]))
True
```

#### ascii()
一つの引数を取ります。repr()と同じように可能であればeval()で評価すると引数と同様のオブジェクトになる文字列を、そうでない場合は、`<>`で囲まれたオブジェクトの情報を返却します。
repr()との違いは非ASCII文字が`\x` `\u` `\U` を使ってユニコードのコードポイントとしてエスケープされるということです。例を見るとわかりやすいかもしれません。

```Python3
>>> # int
... ascii(1)
'1'
>>> eval(ascii(1))
1
>>> # str
... ascii('Ascii Characters')
"'Ascii Characters'"
>>> eval(ascii('Ascii Characters'))
'Ascii Characters'

>>> # 非アスキーな文字列ではエスケープされる。
... ascii('アスキーじゃないお')
"'\\u30a2\\u30b9\\u30ad\\u30fc\\u3058\\u3083\\u306a\\u3044\\u304a'"
>>> eval(ascii('アスキーじゃないお'))
'アスキーじゃないお'
>>> # ↑をrepr()で評価すると
... repr('アスキーじゃないお')
"'アスキーじゃないお'"
>>> eval(repr('アスキーじゃないお'))
'アスキーじゃないお'

>>> # eval()に渡す表現を持たない場合
... ascii(object())
'<object object at 0x7f0055dfc410>'
>>> # このパターンでは評価できないのでエラーになる
... eval(ascii(object()))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    <object object at 0x7f0055dfc410>
    ^
SyntaxError: invalid syntax
```

#### bin()
引数に整数を渡すと、頭に`"0b"`のついた２進数表現の文字列として変換してくれます。整数型ではなく、文字列を返すところに注意してください。結果はPythonの式としてeval()で評価可能です。

```Python3
>>> bin(0)
'0b0'
>>> bin(1)
'0b1'
>>> bin(1023)
'0b1111111111'
>>> bin(-1023)
'-0b1111111111'
>>> eval(bin(1023))
1023
```

#### bool()
引数の値を評価して真ならTrue、偽ならFalseを返却します。
真偽の判定方法は公式ドキュメントの[真理値判定](https://docs.python.org/ja/3/library/stdtypes.html#truth-value-testing) を参照してください。
偽になる値の例を挙げると、`False`, `None`, ,`''`(空文字列), `0`, `0.0`, `[]`, `{}` などです。
オブジェクトの真偽値のデフォルトは真なので、`__bool__()`や`__len__()`を実装していないクラスのインスタンスをbool()に渡すと、返り値はTrueになります。

```Python3
>>> # 引数を渡さない場合はFalse
... bool()
False
>>> # int
... bool(0)
False
>>> bool(1)
True
>>> # str
... bool('')
False
>>> bool('シン')
True
>>> bool([])
False
>>> bool({'The Answer': 'Echigo Seika'})
True
>>> # __bool__()を実装しないクラス
... class MyClass(object):
...     pass
...
>>> bool(MyClass())
True
>>> # __bool__()を実装するクラス
... class MyFalseClass(object):
...     def __bool__(self):
...         return False
...
>>> bool(MyFalseClass())
False
```

ちなみに、Python3.6まではbool()の引数は`x=1`というように名前付き引数の形式を使えたのですが、Python3.7からは位置引数のみとなっています。

```Python3:Python3.6
>>> bool(x=1)
True
```

```Python3:Python3.7
>>> bool(x=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bool() takes no keyword arguments
```

#### breakpoint()
Python3.7で新しく導入された機能です。
Pythonのデバッガのブレイクポイントを簡単に置くことができます。
breakpointはsys.breakpointhook()を呼び出し、デフォルトではpdbモジュールが起動してデバッグモードになります。

```Python3:hello.py
# coding: utf-8

def print_hello():
    # breakpointを設置する。これだけでOK
    breakpoint()
    for c in 'Hello, World!!!!!':
        print(c)

if __name__ == '__main__':
    print_hello()
```

Python3.7から起動すると、pdbの対話モードに入ります。
pdbの使い方は[こちら](https://docs.python.org/ja/3/library/pdb.html)を参照してください。

```shell
$ python3.7 hello.py
> /home/kotaro/hello.py(5)print_hello()
-> for c in 'Hello, World!!!!!':
(Pdb) n
> /home/kotaro/hello.py(6)print_hello()
-> print(c)
(Pdb) n
H
> /home/kotaro/hello.py(5)print_hello()
-> for c in 'Hello, World!!!!!':
(Pdb) n
> /home/kotaro/hello.py(6)print_hello()
-> print(c)
(Pdb) n
e
> /home/kotaro/hello.py(5)print_hello()
-> for c in 'Hello, World!!!!!':
(Pdb) n
> /home/kotaro/hello.py(6)print_hello()
-> print(c)

```

#### bytearray()
bytearrayオブジェクトを生成して返却します。
bytearrayオブジェクトは、bytesオブジェクトと似ていますが、mutable(変更可能)である点が異なります。bytes型のメソッドをほとんど使える他、配列操作を行うことができます。
引数には0-255の間の整数のiterable, 文字列, 整数値などを渡すことができます。

```Python3
>>> # 整数のiterableを渡すとき
... bytearray([97, 98, 99])
bytearray(b'abc')
>>> bytearray([97, 98, 99])[2]
99
>>> # 文字列を渡すときはエンコーディングが必要
... bytearray('バイト配列', 'utf-8')
bytearray(b'\xe3\x83\x90\xe3\x82\xa4\xe3\x83\x88\xe9\x85\x8d\xe5\x88\x97')
>>> bytearray('バイト配列', 'utf-8')[0]
227
>>> # bytes型と同様、decodeできる
... bytearray('バイト配列', 'utf-8').decode('utf-8')
'バイト配列'
>>> # 数値を渡すと、数値の長さのnullバイト列で初期化される
... bytearray(3)
bytearray(b'\x00\x00\x00')

>>> b = bytearray('abc', 'ascii')
>>> id(b)
139844663292400
>>> b
bytearray(b'abc')
>>> # mutableなので変更可能
... b[1]=100
>>> id(b)
139844663292400
>>> b
bytearray(b'adc')
```

#### bytes()
bytes型のオブジェクトを返却します。
bytearray()に似ていますが、こちらはimmutable(変更不可能)なオブジェクトです。
引数にはbytearray()と同様に整数のiterable(0-255), 数値, 文字列を渡すことができます。

````Python3
>>> bytes([97, 98, 99])
b'abc'
>>> bytes(5)
b'\x00\x00\x00\x00\x00'
>>> bytes('バイト', 'utf-8')
b'\xe3\x83\x90\xe3\x82\xa4\xe3\x83\x88'
>>> # immutableなので変更できない
... b = bytes('abc', 'ascii')
>>> b[1] = 100
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'bytes' object does not support item assignment
````

## [第2回](https://qiita.com/ichi_taro3/items/696b355d79d01a810381)に続く
[次回](https://qiita.com/ichi_taro3/items/696b355d79d01a810381)はcallable()から。