100日後にエンジニアになるキミ - 28日目 - Python - Python言語の基礎4

今日はPythonの基礎の続きです。

前回はこちら

[100日後にエンジニアになるキミ - 27日目 - Python - Python演習1](https://qiita.com/otupy/items/1067288fec8d66411e6b)


## リスト

[![表示されなかったらすみません](https://img.youtube.com/vi/xGWGbHG0zuQ/0.jpg)](https://youtu.be/xGWGbHG0zuQ)

プログラム言語の中では特殊なデータの形を取り扱うことができます。
それが`辞書型`や`リスト型`といったデータ構造のものです。

`リスト型`のデータを作るには `[ ]` 四角カッコ　を用います。
四角カッコで括った中に、格納したいデータの形でデータを入力します。

リスト型の値は、要素を複数持つことができます。
リストの値に要素をたくさん入れ込むには　カンマ　でつなぎます。

**リスト型の定義**

`[]`
`[要素,要素,・・・]`

リストの例:
`[1,2,3]`

```
# リスト型
l1 = [1,2,3,4,5]

# 空のリスト(まだ要素を持っていない)
l2 = []

print(l1)
print(l2)
```
[1,2,3,4,5]
[]

`リスト型`というのは複数の要素を持ったデータ構造になっていて、
`リスト型`の中に入れられるデータの形については特に決まりはなく
どんなデータでも入れられます。

```
a = [1,2,3,'4']
print(a)
```
[1, 2, 3, '4']

リストの要素は違うデータ型を混在させることもできます。

`[]`を用いるので`インデックス`と間違えやすいので気をつけましょう。
Python言語のリスト型は`インデックス`を用いて参照します。

**リストの要素の参照**

`リスト型のデータ[インデックス値]`

```
# リストの中にリストを定義
lis_lis = [[1,2,3],[4,5,6],[7,8,9]]
print(lis_lis)

# 取り出しもインデックスで
print(lis_lis[1][2])
```
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
6

リストの中にリストを格納できます。
その場合は多重リストになるので取り出す`[]`の指定も
その多重の分だけ書くことになります。

また`インデックス`には`スライス`という機能があり
開始、終了などを指定すること出来るので
取り出される要素もスライスの仕方で変わります。

`リスト型[インデックス値]` : 1つだけ要素を取り出す。
`リスト型[開始:終了]` : 開始から終了までの複数の要素を取り出せる。
`リスト型[開始:]` : 開始から末尾までの複数の要素を取り出せる。
`リスト型[:終了]` : 最初から終了までの複数の要素を取り出せる。
`リスト型[開始:終了:飛ばす数]`開始から終了までn個飛ばしで複数の要素を取り出せる。

```
a = [1,2,3]
# 最初の要素を取り出す
print(a[0])
print(type(a[0]))
```
1
<class 'int'>

```
a = [1,2,3,4,5]
# 複数の要素を取り出す(3番目から4番目まで)
print(a[2:4])
print(type(a[2:4]))
```
[3, 4]
<class 'list'>

```
a = [1,2,3,4,5]
# 複数の要素を取り出す(２番目から最後まで)
```
print(a[1:])

```
# 複数の要素を取り出す(最初から3番目まで)
print(a[:3])
```
[2, 3, 4, 5]
[1, 2, 3]


リストでは要素の順番が重要になります。
スライスを使うと複数の要素に対応します。




**リストの要素の追加**

リストの要素の追加方法は多岐に渡ります。
値を一つだけ入れるのがappend
その他はリストをリストに追加する方法です。

`変数.append(要素)`

`変数 += リスト`
`変数.extend(リスト)`
`リスト + リスト`


```
a = [1,2,3]
# 要素の追加 append
a.append(4)
print(a)
```
[1, 2, 3, 4]

```
a = [1,2,3]
# 要素の追加 +=
a += a
print(a)
```
[1, 2, 3, 1, 2, 3]

```
a = [1,2,3]

# 要素の追加 extend
a.extend([4,5])
print(a)
```
[1, 2, 3, 4, 5]

```
a = [1,2,3]

# 要素の追加 リスト + リスト
a = a + a
print(a)
```
[1, 2, 3, 1, 2, 3]

リスト型の値は複数の要素をいれ込めるので
取り出し方も様々な取り出し方があります。

**要素の変更**

要素の変更方法は`インデックス`を用いて抽出をした所に
`代入`を行って変更を行います。

`リスト型変数[インデックス値] = 変更後の値`

`リスト型変数[開始:終了] = [リスト]`
`リスト型変数[開始:] = [リスト]`
`リスト型変数[:終了] = [リスト]`

```
a = [1,2,3,4,5]
print(a)
# ３番目の要素を 9 に変更
a[2] = 9
print(a)
```
[1, 2, 3, 4, 5]
[1, 2, 9, 4, 5]

```
a = [1,2,3,4,5]
# 複数の要素を変更(3番目から4番目まで
a[2:4] = [9,8]
print(a)

a = [1,2,3,4,5]
# 複数の要素を変更(２番目から最後まで)
a[1:] = [7,6]
print(a)

a = [1,2,3,4,5]
# 複数の要素を変更(最初から3番目まで)
a[:3] = [8,8,8,8]
print(a)
```
[1, 2, 9, 8, 5]
[1, 7, 6]
[8, 8, 8, 8, 4, 5]


インデックスの開始、終了を用いた場合は複数の要素が同時に置き換わるので
順番にも影響が出ます。注意しましょう。

**要素の削除**

リストから要素を削除する方法もいくつかあります。

***del とインデックスを使う方法***

`del リスト[インデックス値]`
`del リスト[開始:終了]`

```
l = ["A", "B", "C", "D", "E", "F", "G"]
print (l)

# 2番目を削除
del l[1]
print (l)

# さらに2番目,3番目を削除
del l[1:3]
print (l)
```
['A', 'B', 'C', 'D', 'E', 'F', 'G']
['A', 'C', 'D', 'E', 'F', 'G']
['A', 'E', 'F', 'G']

インデックス値1つだけの時は要素1つ
開始終了などで複数指定した場合は、複数の要素が削除されます。

***pop関数を使って削除***

`リスト.pop(インデックス値)`

pop関数を用いる場合、要素が無いとエラーになるので注意しましょう。

```
l = ["A", "B", "C", "D", "E", "F", "G"]
print (l)

# 4番目を削除
l.pop(3)
print (l)
```
['A', 'B', 'C', 'D', 'E', 'F', 'G']
['A', 'B', 'C', 'E', 'F', 'G']

```
l = ["A", "B", "C", "D", "E", "F", "G"]

# 要素がない場合はエラーになる
l.pop(8)
```
IndexError　：
インデックスの値が要素数を超えていたりする場合に発生するエラー

***remove関数を使って削除***

`リスト.remove(指定の値)`
remove関数も、指定の値が無いとエラーになります。

```
l = ["A", "B", "C", "D", "E", "F", "G"]
print(l)

# 要素の A を削除
l.remove('A')
print (l)
```
['A', 'B', 'C', 'D', 'E', 'F', 'G']
['B', 'C', 'D', 'E', 'F', 'G']

```
l = ["A", "B", "C", "D", "E", "F", "G"]

# 要素がない場合はエラーになる
l.remove('H')
```
ValueError :
リストに削除する値が含まれていないから発生したエラー

pop,remove関数で削除するには、有ったら削除するという工夫が必要です。

**リストの要素の検索**

リストの機能ではないですが
`in` 演算子を用いてリストの要素の値の検索ができます。

`値 in リスト型`

`in` 演算子を用いると
中身が検索できて、その結果が`bool`型で返ってきます。

```
l = ["A", "B", "C", "D", "E", "F", "G"]
print ('K' in l)
```
False

このbool型の結果を用いて有ったら削除するということができます。

**リストの要素の並べ替え**

並べ替えは`sort関数`を使って行います。
文字列の場合はABCなどの文字順、数値の場合は数値の大小の順番です。

昇順：`リスト.sort()`
降順：`リスト.sort(reverse=True)`

```
a = [1,4,3,5,6]
print(a)

# 昇順で並び替え
a.sort()
print(a)
```
[1, 4, 3, 5, 6]
[1, 3, 4, 5, 6]

```
a = [1,4,3,5,6]
print(a)

# 降順で並び替え
a.sort(reverse=True)
print(a)
```
[1, 4, 3, 5, 6]
[6, 5, 4, 3, 1]

**要素を逆に並び替える**

要素の大小ではなく、元の順番の逆に並び替える方法です。

`リスト.reverse()`

```
a = [1,4,3,5,6]
print(a)

# 格納した逆の順番で並び替え
a.reverse()
print(a)
```
[1, 4, 3, 5, 6]
[6, 5, 3, 4, 1]


リストは複数の値を確保できるので
様々な用途でプログラムでは用いられます。

使用頻度もTop3くらいにはなるかと思いますので
取り扱い方は押さえておきましょう。

## タプル

[![表示されなかったらすみません](https://img.youtube.com/vi/QCxAEAgvq3I/0.jpg)](https://youtu.be/QCxAEAgvq3I)

リストと同じようなデータとして`タプル型`というものがあります。
`タプル`は、一度定義したら追加、変更などができないデータ型です。

pythonでは`()`　丸括弧　で定義することができます。

`(要素)`

リストとの大きな違いは値の追加や変更ができないという点です。

一度、変数を作ったらその変数の中の要素を変更したり付け足したり
削除したりすることができないリスト　だと思ってください。

なので、用途としては変わることのないものを格納しておく
というような使い方になります。

```
# ５つの要素をもったタプルを定義
a = (1,2,3,4,5)
print(a)
```
(1, 2, 3, 4, 5)

```
# 要素を持たないタプルも定義できるが意味がない
b=()
print(b)
```
()


要素の取り出しについてはリストと同じく
インデックスとスライス機能を使ったりすることができます。

```
# タプルの３番目の要素を取り出す
a = (1,2,3,4,5)
print(a[2])
```
3

```
# タプルの2-4番目の要素を取り出す
a = (1,2,3,4,5)
print(a[1:4])
```
(2, 3, 4)

要素の追加、削除、変更はできません。エラーが発生します。

```
# タプルの要素の追加
c = (1,3,5,7,9)
c.append(11)
```
AttributeError: 'tuple' object has no attribute 'append'

```
# タプルの削除
d = (1,3,5,7,9)
del d[2]
```
TypeError: 'tuple' object doesn't support item deletion

```
# タプルの要素の変更
e =(2,3,4,5,6)
e[3]=13
```
TypeError: 'tuple' object does not support item assignment

定義されたタプルの要素に手を加えようとするとエラーが発生します。

ただし、タプルとタプルを組み合わせて別のタプルを作り
要素の追加のようなことはできます。

```
t1 = (1,2,3,4,5)
t2 = (2,3,4,5,6)
t3 = t1 + t2
print(t3)
```
(1, 2, 3, 4, 5, 2, 3, 4, 5, 6)

このように
一度作ってしまえば要素は変わらないような使いみちであれば
間違って書き換える心配のないタプルが適しています。

タプルという形のデータもあるんだよ、ということを
押さえていただければと思います。


## 辞書型

[![表示されなかったらすみません](https://img.youtube.com/vi/vZQbC8acCkU/0.jpg)](https://youtu.be/vZQbC8acCkU)

リストと同じくpythonの中で最も使われるデータの形が
`辞書型`とよばれるデータ構造です。

辞書型は`キー`と`値を`ペアにして
複数の要素を管理することができます。

キーは`整数`だけではなく、`文字`で設定可能です。
値は様々な型を用いることができます。
また、リストとは違って、順番は特に関係ありません

**辞書型の作成**

辞書型は`{}` 波カッコ　で定義でき
`キー`と`値`を要素として格納できます。

`{キー:値}`

```
# キーが数値の辞書型の例
d1 = {1:10,2:20}
print(d1)
```
{1: 10, 2: 20}

```
# キーが文字列の辞書型の例
d2 = {'a':10,'b':20}
print(d2)
```
{'b': 20, 'a': 10}


**辞書の要素の参照**

`変数名[キー]`で値を返すことができます。

ただし、`キー`が無いと`エラー`になってしまいます。

```
# 5つの要素を登録
sample_dic_data = {'apple': 100, 'banana': 100, 
'orange': 300, 'mango': 400, 'melon': 500}

# キーがmelonの要素を返す
print(sample_dic_data['melon'])
```
500

```
sample_dic_data = {'apple': 100, 'banana': 100, 
'orange': 300, 'mango': 400, 'melon': 500}

# キーがgrapeの要素を返す
print(sample_dic_data['grape'])
```
KeyError: 'grape'

要素の中にそのキーが無い場合は`KeyError`が発生します。
辞書型の機能としては要素の追加、変更、削除もリストと同様にできます。

＊＊要素の追加**

`変数名[キー名] = 値`

```
d3 = {1:2 , 3:4}
print(d3)

# 辞書の要素の追加
d3[5] = 8
print(d3)
```
{1: 2, 3: 4}
{1: 2, 3: 4, 5: 8}


すでに存在するキーを指定した場合は値を上書きして変更されます。

```
d4 = {1:2 , 3:4}
print(d4)

# 辞書の要素の変更
d4[1] = 18
print(d4)
```
{1: 2, 3: 4}
{1: 18, 3: 4}


**キーの検索**

リストと同じように `in` を用いて

`キー in 辞書`

とすると、`キー`が存在している場合は`True`なければ`False`が返ります。

```
d5 = {3:4 , 5:6 , 7:8}

# キー名で検索
print( 7 in d5)
print( 11 in d5)
```
True
False

```
mydict = {'pen':1 , 'pineapple':2 , 'apple':3}
print('apple' in mydict)
```
True

`キー`を`文字列`で設定した場合は探す時の`キー`も`文字列`で
`整数値`で`キー`を設定したら探す時も`整数`の値で探すことになるので
`キー`を検索する際のデータの形は注意しましょう。


**辞書の要素の削除**

***全ての要素の削除***
`辞書変数名.clear()`

***要素を指定して削除***
`del 辞書変数名[キー]`
`辞書変数名.pop(キー)`

`del`は消した値を返さ無いが`pop`は値を返します。

```
d6 = {'pen':1 , 'pineapple':2 , 'apple':3}
print(d6)

# キーで削除
del d6['pen']
print(d6)

# 要素の全削除
d6.clear()
print(d6)
```
{'apple': 3, 'pineapple': 2, 'pen': 1}
{'apple': 3, 'pineapple': 2}
{}

```
d7 = {'pen':1 , 'pineapple':2 , 'apple':3}
print(d7)

# pop関数でキーで削除
print(d7.pop('pen'))
print(d7)
```
{'apple': 3, 'pineapple': 2, 'pen': 1}
1
{'apple': 3, 'pineapple': 2}


popは消した値を用いて何かをする場合に使います。

```
d8 = {'pen':1 , 'pineapple':2 , 'apple':3}
print(d8)

# pop関数で存在しないキーで削除
print(d8.pop('penpen'))
```
KeyError: 'penpen'


値の参照と同じく、存在しないキーを削除するとエラーになります。

キーがない場合でも安全に消したい場合は`pop`に第二引数を追加します。

`辞書変数名.pop(キー名 , 返す値)`

```
d9 = {'pen':1 , 'pineapple':2 , 'apple':3}
print(d9)

# pop関数で存在しないキーで削除
print(d9.pop('penpen' , None))
```
{'apple': 3, 'pineapple': 2, 'pen': 1}
None


こうするとこのキーで要素があった場合はその値を
要素がなければ、第二引数の値を返すようにできます。

`None`を設定しておくと、何も起きないように見えるので
安全に消すことができます。

後の講義に出てくるIF文や検索の機能を使って
キーが有ったら、という工程を挟むことでも
うまく消すことができます。

この消した値を使って何かする場合は、少しだけ
テクニックが必要になるので注意しましょう。

**全ての要素の参照**

辞書型は複数のデータが格納されるので
全ての要素を参照する方法が用意されています。

辞書型の要素は`キー`と`値`で構成されているので次の３つの参照方法があります。

`辞書型変数.keys()` : `キー`の`リスト`を返す。
`辞書型変数.values()` : `値`の`リスト`を返す。
`辞書型変数.items()` : `キーと値`の`リスト`を返す。

```
# 辞書を定義
mydict = {"pen":1, "pineapple":2, "apple":3}

# キーのリストを返す。
print(mydict.keys())

# 値のリストを返す。
print(mydict.values())

# キーと値のリストを返す。
print(mydict.items())
```
dict_keys(['apple', 'pineapple', 'pen'])
dict_values([3, 2, 1])
dict_items([('apple', 3), ('pineapple', 2), ('pen', 1)])

少しややこしいのですが
`辞書型`から`リスト型`に変換されたデータを取得することができます。

`キーと値`の`リスト`を返す `items()`　では
`キーと値`を`タプル型`にまとめたものが
`リスト`の要素として格納されているものが返ってきています。

返ってきた`リスト型`の中身が`タプル型`の値になっているので
そこから`キー`と`値`を取り出す、ということをします。

この全てを参照する使い方については
繰り返しの`for文`のところで詳しくやっていきたいと思いますので
まずは `辞書型`の取り扱い方を覚えましょう。

辞書はpythonのなかでも最もよく使うデータ型になると思いますので
繰り返し試してみるのが良いと思います。



## まとめ

リスト型と辞書型はPython言語の中でもTOP3に入るほど
多用されるデータ型になります。

しかも取り扱うための方法が複雑で多岐に渡ります。

かなり重要な部分ですので、データの定義の仕方や
抽出方法については是非押さえておいてください。

事項の制御文のところでも、たくさん出てきますので
今の機会に覚えてしまいましょう。

君がエンジニアになるまであと72日

## 作者の情報
乙pyのHP：
http://www.otupy.net/

Youtube：
https://www.youtube.com/channel/UCaT7xpeq8n1G_HcJKKSOXMw

Twitter：
https://twitter.com/otupython