Python3系のリスト操作まとめ

http://www.amazon.co.jp/dp/4873117380 より

# スライス
## そもそもスライスの考え方
- ```[:]```は、先頭から末尾までのシーケンス全体を抽出する
- ```[start:]```は、startオフセットから末尾までのシーケンスを抽出する
- ```[:end]```は、先頭からend-1オフセットまでのシーケンスを抽出する
- ```[start:end]```は、startオフセットからend-1オフセットまでのシーケンスを抽出する
- ```[start:end:step]```は、step文字ごとにstartオフセットからend-1オフセットまでのシーケンスを抽出する

オフセットはゼロから右に向かって0, 1, ...となり、末尾から左に向かって-1, -2,...となる。startを指定しなければスライスは0(先頭)を使う。

## 例

```
In [9]: sample_list = ['a','b','c','d','e']

In [10]: sample_list[0]
Out[10]: 'a'

In [11]: sample_list[0:]
Out[11]: ['a', 'b', 'c', 'd', 'e']

In [12]: sample_list[0:-1]
Out[12]: ['a', 'b', 'c', 'd']

In [13]: sample_list[0:4]
Out[13]: ['a', 'b', 'c', 'd']

In [19]: sample_list[-3:]
Out[19]: ['c', 'd', 'e']

In [22]: sample_list[-3:-1]
Out[22]: ['c', 'd']

# リストを反転させるとき
In [14]: sample_list[::-1]
Out[14]: ['e', 'd', 'c', 'b', 'a']
```

# append()
リストの末尾に、一つの要素を追加したい時, ``append()``メソッドを使う

```
In [23]: sample_list.append('f')

In [24]: sample_list
Out[24]: ['a', 'b', 'c', 'd', 'e', 'f']

```

# extend()または+=を使ったリストの結合
extend()を使えば、ふたつのリストをひとつにまとめることができる。これは破壊的操作。

```
In [27]: sample_list.extend(number_list)

In [28]: sample_list
Out[28]: ['a', 'b', 'c', 'd', 'e', 'f', 1, 2, 3]

# sample_listの初期化
In [33]: sample_list = ['a','b','c','d','e']

In [34]: sample_list += number_list

In [35]: sample_list
Out[35]: ['a', 'b', 'c', 'd', 'e', 1, 2, 3]
```

ちなみにappend()はあくまで1つの要素として扱われるので、

```
In [36]: sample_list = ['a','b','c','d','e']
In [37]: sample_list.append(number_list)

In [38]: sample_list
Out[38]: ['a', 'b', 'c', 'd', 'e', [1, 2, 3]]
```

# insert()によるオフセットを指定した要素の追加
append()関数は、リストの末尾にしか要素を追加ｄけいない。リストのオフセットを指定し、その前に要素を追加したいときには、insert()を使う。オフセット0を指定すると、先頭に挿入される。末尾を超えるオフセットを指定すると、append()と同じようにリストの末尾に挿入される。

```
In [42]: sample_list = ['a','b','c','d','e']

In [43]: sample_list.insert(1,1)

In [44]: sample_list
Out[44]: ['a', 1, 'b', 'c', 'd', 'e']

In [45]: sample_list.insert(10,10)

In [46]: sample_list
Out[46]: ['a', 1, 'b', 'c', 'd', 'e', 10]
```

# delによる指定したオフセットの要素の削除
delはメソッドではなく、文なので、注意。

```
In [46]: sample_list
Out[46]: ['a', 1, 'b', 'c', 'd', 'e', 10]

In [48]: del sample_list[-1]

In [49]: sample_list
Out[49]: ['a', 1, 'b', 'c', 'd', 'e']
```

(delとか、lenとか、統一されてない実装は結構混乱する..)


# remove()による値に基づく要素の削除
オフセットがわからない場合、またはどこにあるのかはどうでもいい場合には、remove()を使って値を指定して要素を削除することができる。

```
In [49]: sample_list
Out[49]: ['a', 1, 'b', 'c', 'd', 'e']

In [50]: sample_list.remove(1)

In [51]: sample_list
Out[51]: ['a', 'b', 'c', 'd', 'e']
```

# pop()でオフセットを指定して要素を取り出し、削除する方法
pop()を使うと、リストから要素を取り出し、同時にリストからその要素を削除することができる。オフセットを指定してpop()を呼び出すと、そのオフセットの要素が返される。引数を指定しなければ、オフセットとして-1が使用される。

```
In [51]: sample_list
Out[51]: ['a', 'b', 'c', 'd', 'e']

In [52]: sample_list.pop()
Out[52]: 'e'

In [53]: sample_list
Out[53]: ['a', 'b', 'c', 'd']

In [54]: sample_list.pop(1)
Out[54]: 'b'

In [55]: sample_list
Out[55]: ['a', 'c', 'd']
```

# index()により要素の値から要素のオフセットを知る方法

```
In [56]: sample_list = ['a','b','c','d','e']

In [57]: sample_list.append('a')

In [58]: sample_list
Out[58]: ['a', 'b', 'c', 'd', 'e', 'a']

In [60]: sample_list.index('b')
Out[60]: 1

# 複数ある場合は、オフセットの小さい方
In [61]: sample_list.index('a')
Out[61]: 0
```

# inを使った値の有無のテスト
リストに値があるかどうかをテストするときには、inを使う。

```
In [64]: sample_list
Out[64]: ['a', 'b', 'c', 'd', 'e']

In [65]: 'a' in sample_list
Out[65]: True

In [66]: 'g' in sample_list
Out[66]: False
```

# count()を使った値の個数の計算
特定の値がリスト内に何個含まれているかを数えるにはcount()を使う。

```
In [64]: sample_list
Out[64]: ['a', 'b', 'c', 'd', 'e']

In [67]: sample_list.count('a')
Out[67]: 1

In [68]: sample_list.count('g')
Out[68]: 0

In [69]: sample_list.append('a')

In [70]: sample_list
Out[70]: ['a', 'b', 'c', 'd', 'e', 'a']

In [71]: sample_list.count('a')
Out[71]: 2
```

# sort()による要素の並べ替え
sortは2つある
- メソッドのsort()は、破壊的操作
- 汎用関数のsorted()は、非破壊的操作
	- ソート済みリストのコピーを返す

```
In [76]: names = [ 'Ryoma', 'Toshimichi', 'Tomoatsu']

In [77]: sorted_named = sorted(names)

In [78]: sorted_named
Out[78]: ['Ryoma', 'Tomoatsu', 'Toshimichi']

In [79]: names.sort()

In [80]: names
Out[80]: ['Ryoma', 'Tomoatsu', 'Toshimichi']
```

整数とfloatは、式のなかでPythonが自動的に変換を行うので、併用できる。

```
In [81]: numbers = [2, 1, 4.0, 3]

In [82]: numbers.sort()

In [83]: numbers
Out[83]: [1, 2, 3, 4.0]
```

デフォルトでは、昇順だが、```reverse=True``により、降順にもできる。

```
In [84]: numbers = [2, 1, 4.0, 3]

In [85]: numbers.sort(reverse=True)

In [86]: numbers
Out[86]: [4.0, 3, 2, 1]

```

# =による代入とcopy()によるコピー

``=``では、参照先が同じなので、注意。

```
In [87]: a = [1, 2, 3]

In [88]: b = a

In [89]: b[0] = 'why'

In [90]: b
Out[90]: ['why', 2, 3]

In [91]: a
Out[91]: ['why', 2, 3]
```

コピーするには、次のどれかを使う
- リストのcopy()関数
- list()変換関数
- リストスライス[:]

```
In [92]: a = [1, 2, 3]

In [93]: b = a.copy()

In [94]: c = list(a)

In [95]: d = a[:]

In [96]: a
Out[96]: [1, 2, 3]

In [97]: b
Out[97]: [1, 2, 3]

In [98]: c
Out[98]: [1, 2, 3]

In [99]: d
Out[99]: [1, 2, 3]

In [100]: a[0] = 'why'

In [101]: a
Out[101]: ['why', 2, 3]

In [102]: b
Out[102]: [1, 2, 3]

In [103]: c
Out[103]: [1, 2, 3]

In [104]: d
Out[104]: [1, 2, 3]
```

## list()変換関数について
list()変換関数は、単体で使用するとリストを生成するが、リストやタプルを引数に取るとき、中身の1番外側を展開して、リスト化する。

```
In [107]: a = [1, 2, 3]

In [108]: b = (1, 2, 3)

In [109]: c = list(a)

In [110]: c
Out[110]: [1, 2, 3]

In [111]: d = list(b)

In [112]: d
Out[112]: [1, 2, 3]

In [113]: a.append(b)

In [114]: a
Out[114]: [1, 2, 3, (1, 2, 3)]

In [115]: c = list(a)

In [116]: c
Out[116]: [1, 2, 3, (1, 2, 3)]

```