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

# はじめに
Pythonの勉強をしようと思って触り始めたので、[Python文法詳解](https://www.amazon.co.jp/Python%E6%96%87%E6%B3%95%E8%A9%B3%E8%A7%A3-%E7%9F%B3%E6%9C%AC-%E6%95%A6%E5%A4%AB/dp/4873116880/ref=cm_cr_arp_d_pl_foot_top?ie=UTF8)を読んで「なるほどー」と思ったところをメモります。
普段はJavaをメインで書いているので、おそらくJavaと違うところ中心になると思います。

# 第1章 イントロダクション
- Pythonという名前は「Monty Python's Flying Circus」（コメディ番組）に由来。
- サンプルコードで「foo」「bar」「baz」みたいなやつは「spam」「ham」「egg」を使う習慣になっている。(コントで使っていたらしい)
- 見慣れないワードはこれ由来だと思っとけ、とのこと。

# 第2章 Pythonの実行
```py:_の挙動
>>> 1+1
2
>>> _ # 最後に評価した計算結果が「 _ 」に入る、マジか
2
>>> _ + _ # 2+2=
4
>>> _ # 「 _ 」は4が設定される
4
```
```py:複数処理をまとめて書く（基本やらない）
print(1+1); print('Hello')
```
- pythonではインデントだけでコードブロックを指定する。（「スイート」とも呼ぶ。）
- インデントはスペース4つが標準的な規約。

```py:数値型
>>> 100 # 整数
100
>>> 100.0 # 浮動小数点数
100.0
>>> 0b100 # 2進数
4
>>> 0o100 # 8進数
64
>>> 0x100 # 16進数
256
```
```py:条件演算子の連結
>>> 99
99
>>> 0 < _ < 100  # (0 < _) and (_ < 100)みたいに書かなくていい
True
```
```py:辞書オブジェクト
# いわゆる連想配列・ハッシュテーブル。key & value
>>> {1:'one', 2:'two'}
{1: 'one', 2: 'two'}
>>> {} # 空の辞書
{}

>>> d = {1:'one', 2:'two'}
>>> d[1] # 要素の参照
'one'
>>> d[1] = 'いち' # 要素の値を変更
>>> d[1]
'いち'
>>> d
{1: 'いち', 2: 'two'}
>>> del d[1] # 要素の削除
>>> d[1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 1
>>> d
{2: 'two'}
```
```py:リスト
# リストは更新可能だが、辞書のキーとしては利用できない。
L = [1, 2, 3]
L = [] # 空のリスト
L = [1, 'Two', [3, 4, 5]]
```
```py:タプル
# タプルは更新不能だが、辞書のキーとして利用できる。
t = (1, 2, 3)
t = 1, 2, 3  # ()は必須ではない
t = ()  # 空のタプルは()で表現
t = (1, 'Two', [3, 4, 5])
```
```py:シーケンスのアクセス
# 文字列・リスト・タプルなどの配列はシーケンスと呼ばれ、どの種類のオブジェクトでも同じ方法で要素にアクセスできる。
>>> S = 'abcdefg'  #文字列でも
>>> S[0]
'a'
>>> S[2]
'c'
>>> L = [0, 1, 2, 3, 4, 5]  # リストでも
>>> L[0]
0
>>> L[2]
2

# 負のインデックス値で後ろから取る
>>> S[-1]
'g'
>>> S[-3]
'e'

# 範囲指定して取る
>>> S[1:4]
'bcd'
>>> S[-3:-1]
'ef'
>>> S[:3]  # 開始位置を省略した場合は先頭から、末尾からも同様
'abc'

# 要素の変更
>>> L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> L[0] = 'spam'
>>> L
['spam', 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> L[0:4] = ['ham', 'egg']  # 範囲指定して変更、リストなら要素の数すら無視して更新可能ということらしい
>>> L
['ham', 'egg', 4, 5, 6, 7, 8, 9]
```
## if文
- Pythonのif文では、論理値型のTrueだけでなく、0以外の数値・空ではないコレクションはすべて真。
- 数値の0・空のコレクション・Noneオブジェクトは偽。

## for文
- Pythonのfor文は、__文字列やコレクションに含まれる要素それぞれについて、処理を繰り返し実行する。__

```py:
>>> S = 'spam'

# 文字列型をそのままループさせているように見えて違和感を感じたけど、「要素それぞれについて処理実行」なのであれば
# 「シーケンスはどの種類のオブジェクトでも同じ方法で要素にアクセスできる」ので納得した
# 厳密には「イテラブルオブジェクト」だから（後述）
>>> for c in S:
...     print(c)
... 
s
p
a
m
```
```py:else節
while runnning:
    if not c:
        break
else:
    # whileループがbreakされずに終了した場合に実行、forでも同様
```

## イテラブルオブジェクト
- Pythonのコレクション（リスト・辞書。集合型などのオブジェクトを効率的に操作するためのデータ構造）では、要素オブジェクトを1つずつ順番に取得するためのインタフェース（__イテレータ__）が用意されている。
- イテレータを取得するためのインタフェースを実装したオブジェクトを__イテラブルオブジェクト__と呼ぶ。
- リストも文字列も全てイテラブルオブジェクトなので、さまざまな言語機能・ライブラリで要素の型に依存しない書き方ができるようになっている。（例：for文）
 
```py:ファイルオブジェクトもイテラブル
import sys
for line in sys.stdin:  # 標準入力から一行ずつ読み込む
    print(line, end='')  # 読み込んだ行を標準出力へ書き込む
```

## 関数
```py:関数
>>> def avg(a, b, c):  # 関数定義
...     return (a+b+c)/3
... 
>>> avg(10, 20, 30)
20.0
>>> avg(b=20, c=30, a=10)  # 引数を名前指定して呼び出せる（キーワード引数）、avg(10, 20, 30)と同じ
20.0

>>> def avg(a, b=20, c=30):  # 引数のデフォルト値指定もできる
...     return (a+b+c)/3
... 
>>> avg(10)  # avg(10, 20, 30)と同じ
20.0
```

## クラス
```py:クラス
>>> class Spam:  # クラス定義
...     def ham(self, egg, bacon):  # 第一引数は必ずメソッドが属するオブジェクトを受け取るので、慣例的にselfとする
...         print('ham', egg, bacon)
... 
>>> obj = Spam()
>>> obj.ham('foo', 'bar')  # 'foo'が第二引数、'bar'が第三引数となる
ham foo bar

>>> class Spam2:
...     def __init__(self, ham, egg):  # __init__()メソッドはクラス内にあれば自動で呼び出される（コンストラクタっぽい）
...         self.ham = ham
...         self.egg = egg
... 
>>> obj = Spam2('foo', 'bar')
>>> print(obj.ham, obj.egg)
foo bar

>>> obj.new_attribute = 1  # いきなり属性追加できる。マジか。
>>> print(obj.new_attribute)
1
```