Python3系の基礎文法（リスト、タプル）

# 概要
O'Reilly Japan の「入門 Python 3」及び、下記のPython日本語訳のドキュメントを参考に、
Python3系の基礎文法を勉強します。
同じようにPythonを勉強したいと思ってる方の参考になれば幸いです。

Python 3.6.1 ドキュメント
https://docs.python.jp/3/index.html

# シーケンス型

シーケンス型とは、０個以上の要素を扱うためのデータ構造。
基本的なシーケンス型は、list, tuple, range　等がそれに該当する。

## リスト型 (list)

リストは、ミュータブルなシーケンスで、順序と内容が変わる場合がある場合に向いている。
また、リスト内では同じ値が複数登場しても良い。
（一意な値を管理できれば順番はどうでも良いという場合、集合を使った方が良いかもしれない）

### []またはlist()による作成
```py3
>>> #　空配列の作成　[]
>>> empty_list1 = []
>>> empty_list1
[]

>>> # リスト作成 []
>>> str_list1 = ['A','B','C']
>>> str_list1
['A', 'B', 'C']

>>> #　空配列の作成　list()
>>> empty_list2 = list()
>>> empty_list2
[]

>>> # リスト作成 list()
>>> str_list2 = list(['A','B','C'])
>>> str_list2
['A', 'B', 'C']
```

### 他のデータ型からリスト型への変換
```py3
>>> # 文字列をリストに変換
>>> list('ABC')
['A', 'B', 'C']

>>> # タプルをリストに変換
>>> tuple_sample = ('A','B','C')
>>> list(tuple_sample)
['A', 'B', 'C']

>>> # splitの分割結果をリストに変換
>>> today = '2017/07/01'
>>> today.split('/')
['2017', '07', '01']

>>> # splitの分割結果をリストに変換（空文字要素が含まれる場合）
>>> target = 'A//B/C/DE///F'
>>> target.split('/')
['A', '', 'B', 'C', 'DE', '', '', 'F']
>>> target.split('//')
['A', 'B/C/DE', '/F']
```

### [offset]を指定した要素の取り出し
```py3
>>> target = ['A','B','C']

>>> # 正のインデックスを指定
>>> target[0]
'A'
>>> target[1]
'B'
>>> target[2]
'C'

>>> # 負のインデックスを指定（末尾から逆順に数えていく）
>>> target[-1]
'C'
>>> target[-2]
'B'
>>> target[-3]
'A'

>>> # 範囲外のオフセットが指定された場合はエラー
>>> target[5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
```

### リストのリスト
リスト型は、まちまちの型の要素（他のリスト型も含む）を格納することが可能。

```py3
>>> str_upper = ['A','B','C']
>>> str_lower = ['a','b','c']
>>> str_number = [1 ,'2','3',4]
>>> all_str = [str_upper, str_lower, str_number]

>>> # リストのリスト
>>> all_str
[['A', 'B', 'C'], ['a', 'b', 'c'], [1, '2', '3', 4]]

>>> # リストのリストから第1の要素
>>> all_str[0]
['A', 'B', 'C']

>>> # リストのリストから第2の要素
>>> all_str[1]
['a', 'b', 'c']

>>> # リストのリストから第3の要素
>>> all_str[2]
[1, '2', '3', 4]

>>> # ２個インデックスを指定すると、内臓リストの要素のみ返却される
>>> all_str[1][0]
'a'
```

### [offset]を指定した要素の書き換え
リストはミュータブルなので、オフセットを指定することで値を書き換えることもできる。

```py3
>>> target = ['A','B','C']
>>> target
['A', 'B', 'C']

>>> target[1] = 'V'
>>> target
['A', 'V', 'C']

>>> # リストへの要素追加はappend()により行う
>>> target[3] = 'D'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
```

### [offset]の範囲を指定したスライスによる取り出し
```py3
>>> target = ['A','B','C']
>>> target
['A', 'B', 'C']

>>> # 先頭から
>>> target[0:]
['A', 'B', 'C']

>>> # 先頭から２文字
>>> target[0:2]
['A', 'B']

>>> # リストの要素を逆順にする
>>> target[::-1]
['C', 'B', 'A']
```

### append()による末尾への要素追加
```py3
>>> target = ['A','B','C']
>>> target.append('D')
>>> target
['A', 'B', 'C', 'D']
```

### insert()による要素の追加
append()関数は末尾への要素追加となるため、オフセットを指定して追加位置を指定して、要素を追加したい場合はこちらを使う。
また、末尾を超えるオフセットが指定された場合、リストの末尾に追加される。
（誤ったオフセットに対して例外をは投げられない）

```py3
>>> target = ['A','B','C']

>>> # 3文字目に追加
>>> target.insert(2,'Q')
>>> target
['A', 'B', 'Q', 'C']

>>> # 末尾を超えるオフセットを指定した場合
>>> target.insert(10,'Z')
>>> target
['A', 'B', 'Q', 'C', 'Z']

>>> # 末尾から数える場合
>>> target.insert(-2,'V')
>>> target
['A', 'B', 'Q', 'V', 'C', 'Z']
```

### delによる要素の削除
delはPythonの文であり、リストのメソッドではないため、del()とは書かない。

```py3
>>> target = ['A','B','C','D','E']

>>> # 3文字目を削除
>>> del target[2]
>>> target
['A', 'B', 'D', 'E']

>>> # 末尾を削除
>>> del target[-1]
>>> target
['A', 'B', 'D']
```

### remove()による要素の削除
オフセット指定ではなく、要素を指定して削除する場合は、delではなくこちらを使う。

```py3
>>> target = ['A','B','C','D','E']
>>> target.remove('B')
>>> target
['A', 'C', 'D', 'E']
```

### pop()による要素の取り出しと削除
pop()を使うとリストから要素を取り出し、同時にリストから要素の削除が可能。
引数を指定しない場合、オフセットとして-1(末尾)が指定される。

```py3
>>> target = ['A','B','C','D','E','F','G']
>>> # 3文字目をpop
>>> target.pop(2)
'C'
>>> target
['A', 'B', 'D', 'E', 'F', 'G']

>>> # 末尾文字をpop
>>> target.pop()
'G'
>>> target
['A', 'B', 'D', 'E', 'F']

>>> # 先頭文字をpop
>>> target.pop(0)
'A'
>>> target
['B', 'D', 'E', 'F']
```

### extend()または+=を使ったリストの結合
```py3
>>> # extend()によるリストの結合
>>> target1 = ['A','B','C']
>>> target2 = ['D','E']
>>> target1.extend(target2)
>>> target1
['A', 'B', 'C', 'D', 'E']

>>> # += によるリストの結合
>>> target1 = ['A','B','C']
>>> target2 = ['D','E']
>>> target1 += target2
>>> target1
['A', 'B', 'C', 'D', 'E']
```

### index()による要素のオフセット確認
```py3
>>> target = ['A','B','C','D','E','F','G']
>>> target.index('D')
3
```

### in()を使った値の有無判定
```py3
>>> target = ['A','B','C','D','E','F','G']
>>> 'A' in target
True
>>> 'Z' in target
False
```

### count()を使った値の個数計算
```py3
>>> target = ['A','A','A','B','B','C']
>>> target.count('A')
3
>>> target.count('B')
2
>>> target.count('C')
1
```

### join()による文字列への変換
join()は文字列メソッドであり、リストメソッドではない。

```py3
>>> target = ['A','B','C','D','E','F','G']
>>> ','.join(target)
'A,B,C,D,E,F,G'
```

### len()による要素数の取得
```py3
>>> target = ['A','B','C','D','E','F','G']
>>> len(target)
7
```

### sort()による要素のソート（汎用関数を使用する場合も補足）
```py3
>>> # 汎用関数 sorted() による昇順ソート
>>> target = ['C','E','A','D','B','F']
>>> sorted_target = sorted(target)
>>> sorted_target
['A', 'B', 'C', 'D', 'E', 'F']

>>> # 汎用関数 sorted() による降順ソート
>>> target = ['C','E','A','D','B','F']
>>> sorted_target = sorted(target, reverse=True)
>>> sorted_target
['F', 'E', 'D', 'C', 'B', 'A']

>>> # リスト関数 sort() による昇順ソート
>>> target = ['C','E','A','D','B','F']
>>> target.sort()
>>> target
['A', 'B', 'C', 'D', 'E', 'F']

>>> # リスト関数 sort() による降順ソート
>>> target = ['C','E','A','D','B','F']
>>> target.sort(reverse=True)
>>> target
['F', 'E', 'D', 'C', 'B', 'A']
```

### copy()によるリストのコピー（それ以外のコピー方法も補足）
```py3
>>> target = ['A','B','C']

>>> # リストのcopy()関数によりコピー
>>> target1 = target.copy()
>>> target1
['A', 'B', 'C']

>>> # list()変換関数によりコピー
>>> target2 = list(target)
>>> target2
['A', 'B', 'C']

>>> # リストスライスによりコピー
>>> target3 = target[:]
>>> target3
['A', 'B', 'C']
```

## タプル型（tuple）

タプルはリストとは異なり、イミュータブルなシーケンスであるため、タプルを定義した後に要素の追加や削除、変更といった操作はできない。
また、append()やinsert()などの関数はないため、リストと比べて関数が少ない。

使い分けの仕方としては、定数リストを扱う場合はタプルを使用する。
それ以外の検討ポイントは下記。

- タプルは消費スペースが少ない。
- タプルの要素は書き換えられる危険性がない。
- タプルは辞書のキーとして使える。
- 名前付きタプルは、オブジェクトの単純な代替品として使える。
- 関数の引数は、タプルとして渡される。


### タプルの作成
```py3
>>> # 空タプルの作成
>>> empty_tuple = ()
>>> empty_tuple
()

>>> # 要素が１つのタプル（末尾にカンマをつける）
>>> target1 = 'A',
>>> target1
('A',)

>>> # 要素が複数のタプル（末尾のカンマは省略可能）
>>> target2 = 'A','B','C'
>>> target2
('A', 'B', 'C')

>>> # カッコをつけてもエラーにならないため、こちらの方がタプルだとわかりやすい
>>> target3 = ('A','B','C')
>>> target3
('A', 'B', 'C')
```

### tuple()によるタプルへの変換
```py3
>>> str_list = ['A','B','C']
>>> tuple(str_list)
('A', 'B', 'C')
```

## その他
### シーケンスアンパック
```py3
>>> # リストのアンパック代入
>>> str_list = ['A','B','C']
>>> s1, s2, s3 = str_list
>>> s1
'A'
>>> s2
'B'
>>> s3
'C'

>>> # タプルのアンパック代入
>>> str_tuple = ('A','B','C')
>>> s1, s2, s3 = str_tuple
>>> s1
'A'
>>> s2
'B'
>>> s3
'C'
```