Pythonチュートリアル(4章)の内容を箇条書きでまとめた

前の記事：[Pythonチュートリアル(3章)の内容を箇条書きでまとめた](https://qiita.com/Wakii/items/cc4158d602a7646758d9)

#はじめに
[Python3 エンジニア認定基礎試験](https://www.pythonic-exam.com/exam/basic)対策として、Pythonチュートリアル(書籍)の内容を暗記しやすい箇条書きにまとめた自分用メモです。

##参考資料
Pythonチュートリアル： https://docs.python.org/ja/3/tutorial/
4章： https://docs.python.org/ja/3/tutorial/controlflow.html
書籍： https://www.oreilly.co.jp/books/9784873117539/

#"4章 制御構造ツール"
- Python3 エンジニア認定基礎試験の配点
    - 9 / 40問(22.5%) ☆☆☆☆☆(重要度：大)
- テーマ
    - 条件分岐
    - ループ
    - pass文
    - 関数定義
    - コーディング規約(PEP8)

#4.1 if文
- **if, elif, else** が使える。
    - 条件内のブロックはインデントさせる。
- if, elif の後には条件とコロン : が続く。
    - *if x < 0:*
    - *elif x == 2:*
    - elif は複数記述できる。
- else の後にはコロン : がつく。
    - *else:*
    - ちなみに、Pythonのelseはforやwhileなどのループでも使う(後述)。
- Pythonにswitch文はない。

#(参考)while文
- チュートリアル上は ["3.2 プログラミング、はじめの一歩"](https://qiita.com/Wakii/items/cc4158d602a7646758d9#32-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AF%E3%81%98%E3%82%81%E3%81%AE%E4%B8%80%E6%AD%A9) で解説されている構文。
    - 個人的にforと一緒の方が覚えやすいため、ここに記述。
- **while** 条件式 **:** のように書ける。
    - 条件式が真である限り実行を繰り返す。
    - ループのボディ部分はインデントさせる。
    - whileを入れ子にしたり、whileの中にforを入れることも可能。

#4.2 for文
- Pythonのforは**シーケンス (リストや文字列)** のアイテムをインデックス順にすべて処理する。
- **for** w **in** words **:** のように書ける。
    - ループのボディ部分はインデントさせる。
- ループ対象のアイテムを改変する場合、シーケンスのコピーをループさせることが推奨される。
    - シーケンスのコピーには**スライス表記 (スライシング)** を使うとよい。(->3章)
- forを入れ子にしたり、forの中にwhileを入れることも可能。

#4.3 range()関数
- **range()**関数は等差数列のオブジェクトを返す。
    - range(開始, 終了, 増分) のように書ける。
    - *range(5)* #[0, 1, 2, 3, 4]
    - *range(1, 5)* #[1, 2, 3, 4]
    - *range(0, 10, 3)* #[0, 3, 6, 9]
- forとrange()を組み合わせることで、数値による反復を実現できる。
    - *for idx in range(5):* #idx が 0 から 4 の間、処理を繰り返す。
- range()が返すオブジェクトはリストではなく、**反復可能体 (iterable)**。
    - forのように、反復可能体をターゲットとする構造や関数を**反復子 (iterator)** という。
    - **list()関数**を使うと、反復可能体からリストを作成できる。
        - *test = list(range(5))* #testは[0, 1, 2, 3, 4]のリストになる。
        - list() も反復子である。

#4.4 break文とcontinue文、ループにおけるelse節
- **break**は、それを囲む最も内側のループ (forやwhile) を抜ける。
- **continue**は、それ以降のループ内処理を飛ばして次の反復を始める。
- ループの**else:**は、ループ内でbreakが呼ばれなかった場合に実行される。
    - for や while と、elseは同じインデントで記載する。

#4.5 pass文
- **pass文**は何もしない。
    - 構文的には文が必要だが、何もやることが無い場合(キーボード割込待ちなど)に記述する。

#4.6 関数の定義
- **def** 関数名**(**仮引数リスト**):** のように書ける。
    - 関数のボディ部分はインデントさせる。
- 関数本体の最初の文には、**[docstring](https://qiita.com/Wakii/items/39fb6eee9250c4196a61#476-%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E6%96%87%E5%AD%97%E5%88%97-docstiring)**を書くことができる。
- 関数の引数は、オブジェクトの参照が渡される。
    - つまり、関数側で加えた変更が呼び出し側にも反映される。
- 関数のコール(実行)により、その関数の**ローカルシンボル表**が新しく作られる。
    - **シンボル表**とは名前空間のディレクトリであり、関数のローカル変数用のシンボル表がローカルシンボル表である。
    - 関数内で代入すると、値がローカルシンボル表に格納される。
    - 関数に渡された引数(オブジェクトの参照)もローカルシンボル表に格納される。
    - 関数が関数をコールしたときは、新しい別のローカルシンボル表が作られる。
- 関数名を変数に代入すると、その変数名で関数をコールできる。
    - 関数も変数と同様に、定義すると現在のシンボル表に加えられるため。
    - インタープリタは、ユーザー定義関数という型の値と認識する。
- **return文**は値を一つ返して関数から復帰する。
    - returnで値を指定しないと**None**を返す。
    - returnを書かずに関数の末尾に達してもNoneを返す。
    - Noneは通常インタープリタに無視される。
- ちなみに、4.6 には書かれていないが、関数宣言で定義する引数を**仮引数** (parameter) 、関数コールで渡す引数を**実引数** (argument) と呼ぶ。

#4.7 さらに関数について
##4.7.1 引数のデフォルト値
- 関数の引数に**デフォルト値**を設定できる。
    - デフォルト値を設定した引数は省略可能。
- デフォルト値の評価は、関数を定義した時点・スコープで一度だけ行われる。
    - 可変オブジェクト (リスト, ディクショナリ, クラスのインスタンスなど) をデフォルト値にすると、関数が呼び出されるたびにデフォルト値が変わる可能性がある。
        - 対策として、引数のデフォルト値をNoneにして、関数内でNoneが渡されたら初期化したオブジェクトを引数に代入するといった方法がある。

##4.7.2 キーワード引数
- **キーワード引数**には、以下の二種類がある。
    - コール時にキーワード = 値 の形で渡す引数 ... キーワードと値のペアが一つ
    - 名前の左に ** が付き、ディクショナリ形式で受け取る引数 ... キーワードと値のペアが複数
- キーワード引数に対して、以下を**位置引数**という。
    - 値のみを渡す引数 ... 引数が一つ
    - 名前の左に * が付き、反復可能体の形式で受け取る引数 ... 引数が複数
- 以下のような方法で引数を渡すとエラーになる。 
    - 仮引数リストに書かれていないキーワード引数を渡したとき
    - 一つの引数に対して位置引数とキーワード引数の両方で渡したとき
    - キーワード引数を位置引数より先に渡したとき

##4.7.3 任意引数のリスト
- タプル形式の引数は可変個数の引数になる。
    - 可変個数の引数は仮引数リストの最後に置くこと。
        - 前には通常の引数を置ける。
        - 後ろに通常引数を置くと、可変長引数の一部として扱われてしまう。
    - *args 形式の場合、これより後ろの仮引数はすべてキーワード引数となる。
    - **タプル** はリストと似たシーケンスデータだが、変更不能体 (immutable) で、異なる型のアイテムが混在していることが多い。(->[5.3 タプルとシーケンス](https://qiita.com/Wakii/items/34585aa75bf8c6a5b219#53-%E3%82%BF%E3%83%97%E3%83%AB%E3%81%A8%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B9))

##4.7.4 引数リストのアンパック
- リスト、タプル、ディクショナリの各アイテムを取り出して変数や引数に渡すことを**アンパック**という。
    - リストやタプルは名前の左に * を付けるとアンパックされて位置引数になる。
    - ディクショナリは名前の左に ** を付けるとアンパックされてキーワード引数になる。
- 例えばargs = [0, 10, 3]というリストをrange()関数に*range(0, 10, 3)*のような形で渡したいとき、*range(*args)* と書ける。

##4.7.5 lambda (ラムダ) 式
- **lambda キーワード**を使うと小さな無名関数 (ラムダ関数) が書ける。
    - ラムダ関数は関数オブジェクトが必要な場所すべてに使用できる。
    - 構文上の制限として、単一式しか持てない。
    - 普通の関数定義と同様に、ラムダ関数からもそれを取り囲むスコープの変数が利用できる。
        - 例えば、関数func()の中でラムダ関数を定義した場合、func()のローカル変数をラムダ関数で参照できる。

##4.7.6 ドキュメンテーション文字列 (docstiring)
- 1行目は常にオブジェクトの目的の短く簡潔な要約とすべきである。
    - 1行目は大文字で始まり、ピリオド . で終わること。
- 続けて書く場合は、2行目を空行とし、要約と他の記述を分けるべきである。
- Pythonのパーサは複数行からなる文字列リテラルのインデントを除去しない。
    - 除去したい場合はドキュメントを処理するツールの方で行う。

##4.7.7 関数注釈 (関数アノテーション)
- **関数注釈**は型のメタデータ情報。
    - 完全任意のオプションであり、ユーザー定義関数で使用される。
    - 関数の **\_\_annotations__ 属性**にディクショナリとして格納される。
- 引数注釈の定義は、引数名の後にコロン、式と続ける。
- 返り値注釈の定義は、def文の仮引数リストとコロンの間にリテラル "->" と式を挟む。
    - 記入例：*>>> def f(ham: str, eggs: str = 'eggs') -> str:*

#4.8 幕間つなぎ：コーディングスタイル
- Pythonのコーディング規約に、[**PEP8**](https://pep8-ja.readthedocs.io/ja/latest/) がある。以下に一部を抜粋。
    - インデントは4スペースがちょうどいい。タブは混乱を招くので使わない。
    - 79文字以下で行を折り返す。
    - 関数、クラス、関数内の大きめのブロックの分離に空白行を使う。
    - 可能であればコメント行は独立させる。
    - [docstring](https://qiita.com/Wakii/items/39fb6eee9250c4196a61#476-%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E6%96%87%E5%AD%97%E5%88%97-docstiring)を使う。
    - 演算子の周囲やカンマの後ろにはスペースを入れるが、()のすぐ内側には入れない。
    - クラスや関数には一貫した命名を行う。
        - クラスは CamelCase
        - 関数やメソッドは lower_case_with_underscores
    - メソッドの第一引数としては常に self を使うようにする。
    - エンコーディングはUTF-8(Pythonデフォルト)かASCIIがベスト。
    - 識別子に非ASCIIキャラクタを使わない。

次の記事：[Pythonチュートリアル(5章)の内容を箇条書きでまとめた](https://qiita.com/Wakii/items/34585aa75bf8c6a5b219)