Pythonの代表的な組み込み型

# 概要

普段使いする中で、よく使う組み込み型を紹介する。
全部でなく抜粋なので、詳細が気になる人は[公式ドキュメント](https://docs.python.org/ja/3/library/stdtypes.html)も参照。

# 対象
- `Python`の初歩中の初歩を学習したい人

# 執筆時の環境
- OS: Windows10
- Python: 3.7.3

# 本記事中の定義

## 実行例中の定義

```python
>>> "Pythonインタプリタでの実行コマンド"
# 上のコマンドに対応するターミナルの表示
```

## 用語定義

- リテラル：代数を使わずに書いた数値や文字列。いわゆるべた書き。
- ネスト：入れ子構造のこと。
- キャスト：元の型から別の型に変換すること。

# 紹介する型一覧

- [数値型](#数値型)
    - [int](#int)
    - [float](#float)
    - [complex](#complex)
- [文字列型](#文字列型)
    - [str](#str)
- [シーケンス型](#シーケンス型)
    - [list](#list)
    - [tuple](#tuple)
    - [range](#range)
- [その他](#その他)
    - [set](#set)
    - [dict](#dict)
    - [bool](#bool)

# 数値型

| 種類 | 概要 |
| :-- | :-- |
| [int](#int) | 整数 |
| [float](#float) | 浮動小数 |
| [complex](#complex) | 複素数 |

## `int`

**整数値**を扱う型。`イント`と読む。
表現可能な範囲は、環境のシステムに依存する。
他の言語ではより広範囲を扱う`long`などがあるが、Python3の場合はすべて`int`が包括する(Python2には`long`も存在する)。

### リテラル値の書き方

数字だけの連続した記述は`int`として扱われる。

```python
>>> type(123)
# <class 'int'>
```

### 他の型からの変換(キャスト)

[少数](#`float`)や、[文字列](#str)から変換できる。

```python:float->int
>>> int(123.0)
# 123
```
```python:str->int
>>> int("123")
# 123
```
[少数](#`float`)の小数部は**四捨五入ではなく切り捨て**。

```python:float->int
>>> int(123.9)
# 123
```

[文字列](#str)からの変換は**整数値の文字列のみ対応**。
少数値の文字列や、数値でない文字列からは変換できない.

```python:str->int
>>> int("123.9")  # 少数値の文字列
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# ValueError: invalid literal for int() with base 10: '123.9'

>>> int("one")  # 数値以外の文字列
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# ValueError: invalid literal for int() with base 10: 'one'
```

例外的に、次の3パターンだけは純粋な整数値文字列でなくても変換可能。

- 整数値以外に空白スペースのみが含まれる文字列
- 整数値文字列の先頭につく`+/-`符号文字
- 整数値文字列の桁間に含まれるアンダースコア(バージョン3.6以上)

```python:str->int
>>> int("  123  ")  # 前後に空白スペース
# 123

>>> int("-123")  # 先頭に+/-符号
# -123

>>> int("123_456")  # 桁間にアンダースコア
# 123456
```

## `float`

**浮動少数**を扱う型。`フロート`と読む。
表現可能な範囲は、環境のシステムに依存する。
他言語では`double`などがあるが、pythonでは`float`がすべて包括する。

### リテラル値の書き方

連続する数字と1つの`.`(ドット)で記述した値は、`float`として扱われる。

```python
>>> type(123.4)
# <class 'float'>
```

`e`若しくは`E`を$10^n$の意味として書くこともできる。
この記述では、小数点以下が結果的に`0`になる値でも[整数](#int)にはならない。

```python
>>> 1e3
# 1000.0

>>> type(1e3)
# <class 'float'>

>>> 1E3  # 大文字でもいい
# 1000.0
```

### 他の型からの変換(キャスト)

[整数](#int)や[文字列](#str)から変換できる。

```python:int->float
>>> float(123)
# 123.0
```
```python:str->float
>>> float("123.0")
# 123.0
```

[文字列](#str)からの変換は、整数値文字列でも問題ない。

```python:str->float
>>> float("123")  # 整数値文字列
# 123.0
```

数値ではない文字列は変換不能だが、次の4パターンに限り変換可能。

- 数値以外に空白スペースのみが含まれる文字列
- 数値文字列の先頭につく`+/-`符号文字
- 数値文字列の桁間に含まれるアンダースコア(バージョン3.6以上)
- 数値文字列に含まれる指数表記用の`e`,`E`

```python:str->float
>>> float("  123.4  ")  # 前後に空白スペース
# 123.4

>>> float("-123.4")  # 先頭に+/-符号
# -123.4

>>> float("1_234.567_890")  # 桁間にアンダースコア
# 1234.56789

>>> float("1e3")  # 指数表記
# 1000.0

>>> float("1E3")  # 指数表記(大文字E)
# 1000.0

>>> float("1e-3")  # 指数表記の負数
# 0.001
```

変換ではないが、専用の文字列で指定すると**$\pm\infty$**と**非数**を作ることができる。

```python:infinity
>>> float("infinity")  # "infinity"で無限大
# inf

>>> float("inf")  # "inf"でもいい
# inf

>>> float("-inf")  # 負の無限大も可能
# -inf

>>> float("INF")  # 大文字/小文字は問わない
# inf
```

```python:not_a_number
>>> float("nan")  # "nan"で非数
# nan

>>> float("NAN")  # 大文字/小文字は問わない
# nan
```

## `complex`

**複素数**を扱う型。`コンプレックス`と読む。
実部と虚部を別々に管理できる。
電子回路設計の支援アプリなんかで、インピーダンスの計算する時とか便利。

### リテラル値の書き方

リテラルの数値の末尾に`j`若しくは`J`をつけると`complex`として扱われる。
`j`をつけた数値は虚部として使われる。

```python
>>> type(2j)  # 整数リテラル
# <class 'complex'>

>>> type(2.3j)  # 少数リテラル
# <class 'complex'>

>>> type(2.3J)  # Jは大文字でもよい
# <class 'complex'>
```

リテラルで実部ごと書くときは、普通に`+`/`-`でつなぐだけ。

```python
>>> 1.2+3.4j  # 実部と虚部をまとめて記述
# (1.2+3.4j)

>>> type(1.2+3.4j)  # ちゃんとcomplexとして扱われる
# <class 'complex'>

>>> 1.2-3.4j # '-'で繋いでもいい
# (1.2-3.4j)
```

### 実部と虚部を単独で扱う

`complex`のオブジェクトに対して、実部だけ取り出したいときは`.real`、虚部だけ取り出したい時は`.imag`を末尾につける。

```python
>>> x = 1.2+3.4j
>>> x.real  # 実部だけ取り出す
# 1.2

>>> x.imag  # 虚部だけ取り出す
# 3.4
```

取り出された値の型は`complex`ではなく、[float](#float)になる。

```python
>>> x = 1.2+3.4j
>>> type(x)
# <class 'complex'>
>>> type(x.real)
# <class 'float'>
>>> type(x.imag)
# <class 'float'>
```

生成時に[整数](#`int`)を含めていても、[int型](#int)にはならない。

```python
>>> x = 1+2j
# <class 'complex'>
>>> type(x.real)
# <class 'float'>
>>> type(x.imag)
# <class 'float'>
```

`complex(実部, 虚部)`としてインスタンスを作ることもできる。

```python
>>> complex(1.2, 3.4)
# (1.2+3.4j)
```

虚部を省略して書いた場合でも、虚部が`0j`の`complex`が返ってくる。

```python
>>> complex(1.2)
# (1.2+0j)
```

### 他の型からの変換(キャスト)

[文字列](#`str`)から変換できる。

```python:str->complex
>>> complex("1.2+3j")
# (1.2+3j)

>>> complex("1.2-3j")  # 実部と虚部の間は'-'でもいい
# (1.2-3j)
```

虚部を負数にしたい時に`"実数+-虚数"`という記述はエラーになる。

```python
>>> complex("1.2+-3j")
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# ValueError: complex() arg is a malformed string
```

各部の数値と`+`/`-`符号の間に空白スペースがあってはいけない。

```python:str->complex
>>> complex("1.2 + 3j")
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# ValueError: complex() arg is a malformed string
```

[str](#str)->[float](float)変換で、[例外的に変換できるパターン](#float)は`complex`でも同様。

```python:str->complex
>>> complex("   12.3+45j  ")  # 数値部以外の空白スペース
# (12.3+45j)

>>> complex("-1.2+3j")  # 数値の先頭に符号
# (-1.2+3j)

>>> complex("12.3+4_567j")  # 数値の桁間にアンダースコア
# (12.3+4567j)

>>> complex("1.2e3+4E-2j")  # 指数表記のeとE
(1200+0.04j)
```

# 文字列型

| 種類 | 概要 |
| :-- |:-- |
| [str](#str) | 文字列 |

## `str`

**文字列**を扱う型。`ストリング`若しくは`ストラ`と読む。
他言語では"単一文字は`char`など"の場合があるが、pythonでは文字と文字列の区別はなく、`str`がすべて包括する。

### リテラル値の書き方

`"`(ダブルクォーテーション)若しくは`'`(シングルクォーテーション)で囲んだ範囲は`str`として扱われる。

```python
>>> type("abcd")
# <class 'str'>

>>> type('abcd')  # `'`でも同じ
# <class 'str'>
```

`"`/`'`どちらでもリテラル文字列の範囲を表すが、始めと終わりの記号は統一でないといけない。

```
>>> type("abcd')  # 始めが`"`,終わりが`'`
  File "<stdin>", line 1
    type("abcd')
               ^
SyntaxError: EOL while scanning string literal
```

2つの記号をネストして囲うことは可能。
その場合は、内側の記号は文字列の1部とみなされる。

```python
>>> type("ab'cd'ef")
# <class 'str'>

>>> "ab'cd'ef"  # `'`が文字列の1部
# "ab'cd'ef"

>>> 'ab"cd"ef'  # `"`が文字列の1部
# 'ab"cd"ef'
```

`"`/`'`を文字列の1部に含みたい場合は、`\`(バックスラッシュ)でエスケープして文字列中に入れる。

```python
>>> "ab\"cd\"ef\"gh"
# 'ab"cd"ef"gh'

>>> 'ab\'cd\'ef\'gh'
# "ab'cd'ef'gh"
```

`\`を純粋に含めた文字列としたい場合は、リテラル文字列の接頭辞に`r`をつければいい。
標準で`\`をデリミタに使っている、Windows系のパスとかを扱うときに、知っていると重宝する。

```python
>>> "C:\WorkSpace\tmp\hoge.txt"  # `\t`がタブとして解釈されている
# 'C:\\WorkSpace\tmp\\hoge.txt'

>>> r"C:\WorkSpace\tmp\hoge.txt" # すべての`\`がエスケープされている
# 'C:\\WorkSpace\\tmp\\hoge.txt'
```

### 他の型からの変換(キャスト)

`str`は基本的に変換できないオブジェクトはない。

```python:int->str
>>> str(10)
# '10'
```
```python:float->str
>>> str(1.23)
# '1.23'
```
```python:list->str
>>> str([1, 2, 3])
# `[1, 2, 3]`
```

ただし、変換される形式がどうであるかはまちまち。
`__str__()`,`__repr__()`メソッドを未定義のクラスの場合は、インスタンスのIDが表示される。

```python
>>> class Hoge:
...     pass
...
>>> str(Hoge())
# '<__main__.Hoge object at 0x00000123456789AB>'
```

`__str__`メソッドをオーバーライドすれば、任意の形式にできるので、特に問題ではない。

```python
>>> class Hoge:
...     def __str__(self):
...         return "hoge"
...
>>> str(Hoge())
# 'hoge'
```

# シーケンス型

| 種類 | 概要 |
| :-- | :-- |
| [list](#list) | **変更可能**な配列 |
| [tuple](#tuple) | **変更不能**な配列 |
| [range](#range) |  規則的な数値範囲の配列 |

## `list`

**内容が変更可能(ミュータブルな配列**を扱う型。`リスト`と読む。
要素の挿入・削除やソートといった機能のメソッドも持っている。

### 書き方(インスタンスの作り方)

`[`と`]`とで囲うように書くと、`list`として認識される。

```python
>>> type([])
# <class 'list'>

>>> []
# []
```

`[`と`]`の間に書いた要素はリストの要素として扱われる。
複数の要素を入れるときは、`,`を区切りとして書くことができる。
他言語では、"配列の要素の型"を統一しないといけないのもあるが、pythonの場合は異なる型でも同じ配列にできる。

```python
>>> [1,2,3]
# [1, 2, 3]

>>> [1,2.3,"45"]  # 要素の型は統一しなくてもいい
# [1, 2.3, '45']
```

`,`の前後には空白スペースがいくつあっても問題ないが、慣例的に`,`の**前は空白なし**、**後ろは1つの空白を開けてから記述**が見通しがいいとされる。

```python
>>> [1   ,2.3, 45     ]  # 適当に空白あっても認識する
# [1, 2.3, 45]

>>> [1, 2.3, 45]  # 慣例的にはこの書き方がよいとされる
# [1, 2.3, 45]
```

空のリストを作る時は`list()`で作ってもいい。
名前がズバリなので、こっちのほうが見通しはいい感じもするが、タイプ数的には`[]`のほうが楽なのでどちらがいいかは好みによる。

```python
>>> []
# []

>>> list()  # これでも同じ
# []
```

多次元配列は`list`に`list`を入れる。

```python
>>> [[1, 2], [3, 4]]  # 2次元配列
# [[1, 2], [3, 4]]

>>> [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]  # 3次元配列
# [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
```

同一次元の`list`の要素数が違っても問題ない。

```python
>>> [[1, 2], [3, 4, 5]]  # 0番目の要素は2つ、1番目(0始まり)の要素は3つ
# [[1, 2], [3, 4, 5]]
```

### 特定要素の参照・追加

`list`の要素参照方法は、[tuple](#tuple)や[range](#range)の要素参照方法と全く同じなので、それらを読んでいるなら読み飛ばして問題ない。

#### 単一要素の参照

`list`型のオブジェクトの末尾に、`[参照したい要素のインデックス]`をつければ、その要素を参照できる。
なお、インデックスは先頭を`0`として数える。

```python
>>> [1, 2, 3][0]
# 1

>>> [1, 2, 3][1]
# 2
```

`list`の要素数を超えたインデックスの指定はできない。

```python
>>> [1, 2, 3][100]
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# IndexError: list index out of range
```

インデックスを負数で表すと末尾から逆順に参照できる。
ただし、末尾からの場合は`-1`から数える。

任意要素の参照という目的より、"要素数不定の`list`で末尾要素を取りたい"というシチュエーションで重宝する。

```python
>>> [1, 2, 3][-1]  # 逆順の先頭
# 3

>>> [1, 2, 3][-3]  # 逆順での順番指定もできる
# 1

>>> [1, 2, 3][-100]  # 逆順でも要素数を超える指定はできない
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# IndexError: list index out of range
```

#### 複数要素の参照(スライス)

`[i:j]`と書くと、"`i`番目の要素から`j`番目の要素まで"の部分配列を取り出せる。
なお、`i`番目の要素は含み、`j`番目の要素は含まれない。

```python
>>> [1, 2, 3, 4, 5][1:4]
# [2, 3, 4]
```

`j`=`i`+1だと取得する要素は1つだが、`[i]`とは違い要素が1つの`list`が返ってくる。

```python
>>> [1, 2, 3, 4, 5][1:2]  # [1:2]だと2番目(0始まり)の要素だけのlist
# [2]
>>> type([1, 2, 3, 4, 5][1:2])
# <class 'list'>

>>> [1, 2, 3, 4, 5][1]  # [1]だと2番目(0始まり)の要素そのもの
# 2
>>> type([1, 2, 3, 4, 5][1])
# <class 'int'>
```

`i`$\ge$`j`の関係でもエラーにはならず、空の`list`が返ってくる。

```python
>>> [1, 2, 3, 4, 5][2:2]  # iとjが等しい場合
# []

>>> [1, 2, 3, 4, 5][3:1] # i>jの場合
# []
```

`i`番目から末尾までの指定は`[i:]`と省略して表記できる。
同様に、先頭から`j`番目までの指定は`[:j]`と表記できる。

```python
>>> [1, 2, 3, 4, 5][1:]  # 1番目(0始まり)から末尾
# [2, 3, 4, 5]

>>> [1, 2, 3, 4, 5][:4]  # 先頭から4番目(0始まり)まで
# [1, 2, 3, 4]
```

逆順インデックスでの指定もできるが、直観的にわかりにくいわりに利点が薄いので、**基本は使わないほうが無難**。
ただし、要素数不定の`list`で"末尾から`i`個分"という指定をしたい時は、直観的にもわかりやすいので**例外的に使ってもいいと思う**。

```python
>>> [1, 2, 3, 4, 5][-4:-1]  # 逆順の4番目(1始まり)から逆順の1番目(1始まり)まで
# [2, 3, 4]

>>> [1, 2, 3, 4, 5][-3:]  # 末尾から3つ分
# [3, 4, 5]
```

`[i:j:k]`と書くと、"`i`番目の要素から`j`番目の要素までを`k`個毎"の部分配列を取得できる。
`j`を省略して`i`と`k`組合せで、"`i`番目を起点に`k`の倍数毎に抽出した配列"を取得するのに便利(偶数番目要素と奇数番目要素への仕分けなど)

```python
>>> [1, 2, 3, 4, 5][1:4:2]  # 1番目(0始まり)から4番目(0始まり)までを2つ毎
# [2, 4]

>>> [1, 2, 3, 4, 5][1:4:1] # kが1なら[1:4]と同じ
# [2, 3, 4]

>>> [1, 2, 3, 4, 5][::2]  # 偶数番目(0始まり数え)のみ抽出
# [1, 3, 5]

>>> [1, 2, 3, 4, 5][1::2]  # 奇数番目(0始まり数え)のみ抽出
# [2, 4]
```

`k`に負数を書くと、逆順の`list`が戻ってくる。
一応、`i`と`j`も指定できるが、基準の`list`は逆順で考えつつ、`i`と`j`の値は元の順で考えないといけないので**かなりややこしい**。
"`k`だけ指定で逆順`list`を取得する"程度の使い方にとどめるのが無難。

```python
>>> [1, 2, 3, 4, 5][::-1]  # 逆順に取得(実用的)
# [5, 4, 3, 2, 1]

>>> [1, 2, 3, 4, 5][::-2]  # 偶数番目(0始まり数え)のみ抽出(これはまだマシ)
# [5, 3, 1]

>>> [1, 2, 3, 4, 5][-2::-2]  # 奇数番目(0始まり数え)のみ抽出(-2番目(1始まり)を基準に逆順に2つ毎...ややこしい)
# [4, 2]
```

#### 単一要素の追加

`append(x)`メソッドで末尾に要素`x`を追加できる。

```python
>>> hoge = [1, 2, 3]  # [1, 2, 3]というリストを"hoge"という名前で作る
>>> hoge
# [1, 2, 3]
>>> hoge.append(4)  # 末尾に4を追加
>>> hoge
# [1, 2, 3, 4]
```

任意の場所`i`に要素`x`を追加したい時は`insert(i, x)`メソッドを使う。
`i`は逆順指定でもいい。

```python
>>> hoge = [1, 2, 3]  # [1, 2, 3]というリストを"hoge"という名前で作る
>>> hoge
# [1, 2, 3]
>>> hoge.insert(2, 4)  # 2番目(0始まり)に4を追加
>>> hoge
# [1, 2, 4, 3]

>>> hoge.insert(-2, 5)  # 逆順の指定でもいい
>>> hoge
# [1, 2, 5, 4, 3]
```

なお、`i`は要素数の範囲を指定していたら自動的に末尾になる(逆順指定なら先頭)。
単に`append`メソッドの代わりとして使うのはもちろんのこと、一応"`i`番目までは元の順序で、それ以降は逆順"という処理をトリッキーに書けたりするが、どちらにしても**可読性はよくないので控えたほうがいい**。

```python:insertメソッドで書いたときの可読性
>>> hoge = [1, 2, 3]
>>> hoge.insert(100, 4)  # 上の行でhogeが3要素であることを認識していないと、"10番目(0始まり)に挿入したい"という意図に見える
>>> hoge
# [1, 2, 3, 4]
```

```python:appendメソッドで書いたときの可読性
>>> hoge = [1, 2, 3]
>>> hoge.append(4)  # この行だけで"末尾に追加したい"という意図がわかる
```

#### 複数要素の追加

`extend(x)`メソッドで、末尾に[シーケンス型](#シーケンス型)オブジェクト`x`に含まれる全要素を追加できる。

```python
>>> hoge = [1, 2, 3]
>>> hoge
# [1, 2, 3]
>>> hoge.extend([4, 5])  # 末尾に4, 5を追加
>>> hoge
# [1, 2, 3, 4, 5]
```

`x`が[シーケンス型](#シーケンス型)のオブジェクト以外だとエラーになる。

```python
>>> hoge.extend(1)  # intとかは指定できない
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: 'int' object is not iterable
```

任意の場所`i`に[シーケンス型](#シーケンス型)オブジェクト`x`に含まれる全要素を追加したい時は、`追加先のlistインスタンス[i:i] = x`と書けばいい。
`i`は逆順指定でもいい。

```python
>>> hoge = [1, 2, 3]
>>> hoge[2:2] = [4, 5]  # 2番目(0始まり)に4, 5を追加
>>> hoge
# [1, 2, 4, 5, 3]

>>> hoge = [1, 2, 3]
>>> hoge[-1:-1] = [4, 5]  # 逆順で指定してもいい
>>> hoge
# [1, 2, 4, 5, 3]
```

`i`で指定する値は、`追加先のlistインスタンス`の要素数を超えていても自動的に末尾になる。
ただ、単一要素を追加する`insert`メソッド同様、**可読性はよくないので控えたほうがいい**。

```python:[]で書いた場合の可読性
>>> hoge = [1, 2, 3]
>>> hoge[10:10] = [4, 5]  # 上の行でhogeが3要素であることを認識していないと、"10番目(0始まり)に挿入したい"という意図に見える
>>> hoge
# [1, 2, 3, 4, 5]
```

```python:extendメソッドで書いた場合の可読性
>>> hoge = [1, 2, 3]
>>> hoge.extend([4, 5])  # この行だけで"末尾に追加したい"という意図がわかる
>>> hoge
# [1, 2, 3, 4, 5]
```

## `tuple`

**内容が変更不可能(イミュータブル)な配列**を扱う型。`タプル`と読む。

### 書き方(インスタンスの作り方)

`(`と`)`とで囲うように書くと、`tuple`として認識される。

```python
>>> type(())
# <class 'tuple'>

>>> ()
# ()
```

**↓↓↓19'9/9修正:コメントでご指摘いただきました。ありがとうございます。↓↓↓**
~~`(`と`)`の間に書いた要素は`tuple`の要素として扱われる。
複数の要素を入れるときは、`,`を区切りとして書く。~~
`,`で繋いだ複数の要素は`tuple`として認識される。

```python
>>> a = 1, 2, 3
>>> type(a)
# <class 'tuple'>
```
**↑↑↑修正終わり↑↑↑**

他言語では、"配列の要素の型"を統一しないといけないのもあるが、pythonの場合は異なる型でも同じ配列にできる。

```python
>>> (1,2,3)
# (1, 2, 3)

>>> (1,2.3,"45")  # 要素の型は統一しなくてもいい
# (1, 2.3, '45')
```

[list](#list)同様、`,`の前後には空白スペースがいくつあっても問題ないが、慣例的に`,`の**前は空白なし**、**後ろは1つの空白を開けてから記述**が見通しがいいとされる。

```python
>>> (1   ,2.3, 45     )  # 適当に空白あっても認識する
# (1, 2.3, 45)

>>> (1, 2.3, 45)  # 慣例的にはこの書き方がよいとされる
# (1, 2.3, 45)
```

[list](#list)は要素が1つなら`,`があっても無くても[list](#list)として認識されたが、`tuple`の場合は**要素が1つでも`,`をつけないと、その要素の型で認識されてしまう**。

```python
>>> [1,]  # 要素1つのlistとして認識される
# [1]
>>> type([1,])
# <class 'list'>

>>> (1,)  # 要素1つのtupleとして認識される
# (1,)
>>> type((1,))
# <class 'tuple'>

>>> [1]  # 要素1つのlistとして認識される([1,]と同じ)
# [1]
>>> type([1])
# <class 'list'>

>>> (1)  # ただのint型として認識される
# 1
>>> type((1))
# <class 'int'>
```

一応、`tuple()`で空のタプルを作れる。
ただ、[list](#list)と違い変更できないので、(たぶん)使い道はない。

```python
>>> tuple()
# ()
```

多次元配列は`tuple`に`tuple`を入れる。

```python
>>> ((1, 2), (3, 4))  # 2次元配列
# ((1, 2), (3, 4))

>>> (((1, 2), (3, 4)), ((5, 6), (7, 8)))  # 3次元配列
# (((1, 2), (3, 4)), ((5, 6), (7, 8)))
```

同一次元の`tuple`の要素数が違っても問題ない。

```python
>>> ((1, 2), (3, 4, 5))  # 0番目の要素は2つ、1番目(0始まり)の要素は3つ
((1, 2), (3, 4, 5))
```

### 特定要素の参照

`tuple`の要素参照方法は、[list](#list)や[range](#range)の要素参照方法と全く同じなので、それらを読んでいるなら読み飛ばして問題ない。
(順番に読んでいる人 -> [次へ](#range))

#### 単一要素の参照

`tuple`型のオブジェクトの末尾に、`[参照したい要素のインデックス]`をつければ、その要素を参照できる。
なお、インデックスは先頭を`0`として数える。

```python
>>> (1, 2, 3)[0]
# 1

>>> (1, 2, 3)[1]
# 2
```

`tuple`の要素数を超えたインデックスの指定はできない。

```python
>>> (1, 2, 3)[100]
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# IndexError: tuple index out of range
```

インデックスを負数で表すと末尾から逆順に参照できる。
ただし、末尾からの場合は`-1`から数える。

任意要素の参照という目的より、"要素数不定の`tuple`で末尾要素を取りたい"というシチュエーションで重宝する。

```python
>>> (1, 2, 3)[-1]  # 逆順の先頭
# 3

>>> (1, 2, 3)[-3]  # 逆順での順番指定もできる
# 1

>>> (1, 2, 3)[-100]  # 逆順でも要素数を超える指定はできない
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# IndexError: tuple index out of range
```

#### 複数要素の参照(スライス)

`[i:j]`と書くと、"`i`番目の要素から`j`番目の要素まで"の部分配列を取り出せる。
なお、`i`番目の要素は含み、`j`番目の要素は含まれない。

```python
>>> (1, 2, 3, 4, 5)[1:4]
# (2, 3, 4)
```

`j`=`i`+1だと取得する要素は1つだが、`[i]`とは違い要素が1つの`tuple`が返ってくる。

```python
>>> (1, 2, 3, 4, 5)[1:2]  # [1:2]だと2番目(0始まり)の要素だけのtuple
# (2,)
>>> type((1, 2, 3, 4, 5)[1:2])
# <class 'tuple'>

>>> (1, 2, 3, 4, 5)[1]  # [1]だと2番目(0始まり)の要素そのもの
# 2
>>> type((1, 2, 3, 4, 5)[1])
# <class 'int'>
```

`i`$\ge$`j`の関係でもエラーにはならず、空の`tuple`が返ってくる。

```python
>>> (1, 2, 3, 4, 5)[2:2]  # iとjが等しい場合
# ()

>>> (1, 2, 3, 4, 5)[3:1]  # i>jの場合
# ()
```

`i`番目から末尾までの指定は`[i:]`と省略して表記できる。
同様に、先頭から`j`番目までの指定は`[:j]`と表記できる。

```python
>>> (1, 2, 3, 4, 5)[1:]  # 1番目(0始まり)から末尾
# (2, 3, 4, 5)

>>> (1, 2, 3, 4, 5)[:4]  # 先頭から4番目(0始まり)まで
# (1, 2, 3, 4)
```

逆順インデックスでの指定もできるが、直観的にわかりにくいわりに利点が薄いので、**基本は使わないほうが無難**。
ただし、要素数不定の`tuple`で"末尾から`i`個分"という指定をしたい時は、直観的にもわかりやすいので**例外的に使ってもいいと思う**。

```python
>>> (1, 2, 3, 4, 5)[-4:-1]  # 逆順の4番目から逆順の1番目まで
# (2, 3, 4)

>>> (1, 2, 3, 4, 5)[-3:]  # 末尾から3つ分
# (3, 4, 5)
```

`[i:j:k]`と書くと、"`i`番目の要素から`j`番目の要素までを`k`個毎"の部分配列を取得できる。
`j`を省略して`i`と`k`組合せで、"`i`番目を起点に`k`の倍数毎に抽出した配列"を取得するのに便利(偶数番目要素と奇数番目要素への仕分けなど)

```python
>>> (1, 2, 3, 4, 5)[1:4:2]  # 1番目(0始まり)から4番目(0始まり)までを2つ毎
# (2, 4)

>>> (1, 2, 3, 4, 5)[1:4:1] # kが1なら[1:4]と同じ
# (2, 3, 4)

>>> (1, 2, 3, 4, 5)[::2]  # 偶数番目(0始まり数え)のみ抽出
# (1, 3, 5)

>>> (1, 2, 3, 4, 5)[1::2]  # 奇数番目(0始まり数え)のみ抽出
# (2, 4)
```

`k`に負数を書くと、逆順の`tuple`が戻ってくる。
一応、`i`と`j`も指定できるが、基準の`tuple`は逆順で考えつつ、`i`と`j`の値は元の順で考えないといけないので**かなりややこしい**。
"`k`だけ指定で逆順`tuple`を取得する"程度の使い方にとどめるのが無難。

```python
>>> (1, 2, 3, 4, 5)[::-1]  # 逆順に取得(実用的)
# (5, 4, 3, 2, 1)

>>> (1, 2, 3, 4, 5)[::-2]  # 偶数番目(0始まり数え)のみ抽出(これはまだマシ)
# (5, 3, 1)

>>> (1, 2, 3, 4, 5)[-2::-2]  # 奇数(0始まり数え)番目のみ抽出(-2番目を基準に逆順に2つ毎...ややこしい)
# (4, 2)
```

## `range`

**内容が変更不可能(イミュータブル)な、連続する整数要素の配列**を扱う型。`レンジ`と読む。
回数を指定しての繰り返し処理条件などに使える。
[list](#list)や[tuple](#tuple)で同様の配列を作るより、"広範囲の配列を短い構文で定義"でき、"所要するメモリも少ない"。

なお、`range`は出力の見た目がわかりにくいので、実行例には[tuple](#tuple)に変換した出力を併記しておく。

### 書き方(インスタンスの作り方)

`range(stop)`で`0`から整数`stop`までの`range`が作成できる。
要素に`stop`は含まれない。

```python
>>> type(range(10))
# <class 'range'>

>>> range(10)
# range(0, 10)
>>> tuple(range(10))
# (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
```

`0`以外から始まるようにしたい場合は、`range(start, stop)`とすると"`start`から`stop`まで"として作成できる。
要素に`start`は含み、`stop`は含まない。

```python
>>> range(5, 10)  # 5から10で作る
# range(5, 10)
>>> tuple(range(5, 10))
# (5, 6, 7, 8, 9)
```

`start`,`stop`は負数でもいい。

```python
>>> range(-5, 5)  # -5から+5まで
# range(-5, 5)
>>> tuple(range(-5, 5))
# (-5, -4, -3, -2, -1, 0, 1, 2, 3, 4)
```

`start`$\ge$`stop`の場合でも作成はできる。
ただし、"要素は空"の扱いになる。

```python
>>> range(5, 1)  # インスタンス自体は作れる
# range(5, 1)

>>> tuple(range(5, 1))  # 要素を取ろうとすると空っぽ
# ()

>>> range(5, 5)  # start=stopでも同じ
# range(5, 5)
>>> tuple(range(5, 5))
# ()
```

`range(start, stop, step)`とすると、"`start`から`stop`まで`step`毎"として作成できる。

```python
>>> range(1, 10, 2)  # 1から10まで2つ毎で作る
# range(1, 10, 2)
>>> tuple(range(1, 10, 2))  # 出力の見た目にわからないので、tupleとして表示してみる
# (1, 3, 5, 7, 9)
```

`step`に負の値を指定すると"`start`から`stop`まで降順"になる。
ただし、"`start`から`stop`まで降順"なので、今までと逆に`start`$\gt$`stop`が有用になり、`start`$\le$`stop`だと"要素が空"の扱いになる。

```python
>>> range(10, 0, -1)  # 10から0まで降順
# range(10, 0, -1)
>>> tuple(range(10, 0, -1))
# (10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

>>> range(10, 0, -2)  # 負数でもstep値の大きさは有効
# range(10, 0, -2)
>>> tuple(range(10, 0, -2))
# (10, 8, 6, 4, 2)

>>> range(-1, -10, -1)  # start,stopに負数があっても同じ
# range(-1, -10, -1)
>>> tuple(range(-1, -10, -1)) 
# (-1, -2, -3, -4, -5, -6, -7, -8, -9)

>>> range(1, 10, -1)  # stepが正数の時に有効だった、start <　stopの関係は逆に無効(空扱い)になる
range(1, 10, -1)
>>> tuple(range(1, 10, -1))
()
```

なお、`range`は"連続する整数"を扱うものなので、[int](#int)以外の型は使えない。
たとえ、"少数部が`0`の[float](#float)"や"整数文字列の[str](#str)"だとしてもエラーになる。

```python
>>> range(1.2)  # int以外は使えない
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: 'float' object cannot be interpreted as an integer

>>> range(1.0, 10.0)  # 小数部が0でもintでない限りはダメ
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: 'float' object cannot be interpreted as an integer

>>> range("1", "10")  # 整数文字列も同様に使えない
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: 'str' object cannot be interpreted as an integer
```

### 特定要素の参照

`range`の要素参照方法は、[list](#list)や[tuple](#tuple)の要素参照方法と全く同じなので、それらを読んでいるなら読み飛ばして問題ない。
(順番に読んでいる人 -> [次へ](#その他))

#### 単一要素の参照

`range`型のオブジェクトの末尾に、`[参照したい要素のインデックス]`をつければ、その要素を参照できる。
なお、インデックスは先頭を`0`として数える。

```python
>>> range(1, 10)[0]
# 1

>>> range(1, 10)[5]
# 6
```

`range`の要素数を超えたインデックスの指定はできない。

```python
>>> range(1, 10)[100]
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# IndexError: range object index out of range
```

インデックスを負数で表すと末尾から逆順に参照できる。
ただし、末尾からの場合は`-1`から数える。

```python
>>> range(1, 10)[-1]  # 逆順の先頭
# 9

>>> range(1, 10)[-3]  # 逆順での順番指定もできる
# 7

>>> range(1, 10)[-100]
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# IndexError: range object index out of range
```

#### 複数要素の参照(スライス)

`[i:j]`と書くと、"`i`番目の要素から`j`番目の要素まで"の部分配列を取り出せる。
なお、`i`番目の要素は含み、`j`番目の要素は含まれない。

```python
>>> range(1, 10)[1:4]
# range(2, 5)
>>> tuple(range(1, 10)[1:4])
# (2, 3, 4)
```

`j`=`i`+1だと取得する要素は1つだが、`[i]`とは違い要素が1つの`range`が返ってくる。

```python
>>> range(1, 10)[1:2]  # [1:2]だと2番目(0始まり)の要素だけのrange
# range(2, 3)
>>> tuple(range(1, 10)[1:2])
# (2,)
>>> type(range(1, 10)[1:2])
# <class 'range'>

>>> range(1, 10)[1]  # [1]だと2番目(0始まり)の要素そのもの
# 2
>>> type(range(1, 10)[1])
# <class 'int'>
```

`i`$\ge$`j`の関係でもエラーにはならず、空の`range`が返ってくる。

```python
>>> range(1, 10)[2:2]  # iとjが等しい場合
# range(3, 3)
>>> tuple(range(1, 10)[2:2])
# ()

>>> range(1, 10)[3:1]  # i>jの場合
# range(4, 2)
>>> tuple(range(1, 10)[3:1])
# ()
```

`i`番目から末尾までの指定は`[i:]`と省略して表記できる。
同様に、先頭から`j`番目までの指定は`[:j]`と表記できる。

```python
>>> range(1, 10)[1:]  # 1番目(0始まり)から末尾
# range(2, 10)
>>> tuple(range(1, 10)[1:])
# (2, 3, 4, 5, 6, 7, 8, 9)

>>> range(1, 10)[:4]  # 先頭から4番目(0始まり)まで
# range(1, 5)
>>> tuple(range(1, 10)[:4])
# (1, 2, 3, 4)
```

逆順インデックスでの指定もできるが、直観的にわかりにくいわりに利点が薄いので、**基本は使わないほうが無難**。
ただし、要素数不定の`range`で"末尾から`i`個分"という指定をしたい時は、直観的にもわかりやすいので**例外的に使ってもいいと思う**。

```python
>>> range(1, 10)[-4:-1]  # 逆順の4番目から逆順の1番目まで
# range(6, 9)
>>> tuple(range(1, 10)[-4:-1])
# (6, 7, 8)

>>> range(1, 10)[-3:]  # 末尾から3つ分
# range(7, 10)
>>> tuple(range(1, 10)[-3:])
# (7, 8, 9)
```

`[i:j:k]`と書くと、"`i`番目の要素から`j`番目の要素までを`k`個毎"の部分配列を取得できる。
`j`を省略して`i`と`k`組合せで、"`i`番目を起点に`k`の倍数毎に抽出した配列"を取得するのに便利(偶数番目要素と奇数番目要素への仕分けなど)

```python
>>> range(1, 10)[1:4:2]  # 1番目(0始まり)から4番目(0始まり)までを2つ毎
# range(2, 5, 2)
>>> tuple(range(1, 10)[1:4:2])
# (2, 4)

>>> range(1, 10)[1:4:1] # kが1なら[1:4]と同じ
# range(2, 5)
>>> tuple(range(1, 10)[1:4:1])
# (2, 3, 4)

>>> range(1, 10)[::2]  # 偶数番目(0始まり数え)のみ抽出
# range(1, 10, 2)
>>> tuple(range(1, 10)[::2])
# (1, 3, 5, 7, 9)

>>> range(1, 10)[1::2]  # 奇数番目(0始まり数え)のみ抽出
# range(2, 10, 2)
>>> tuple(range(1, 10)[1::2])
# (2, 4, 6, 8)
```

`k`に負数を書くと、逆順の`range`が戻ってくる。
一応、`i`と`j`も指定できるが、基準の`range`は逆順で考えつつ、`i`と`j`の値は元の順で考えないといけないので**かなりややこしい**。
"`k`だけ指定で逆順`range`を取得する"程度の使い方にとどめるのが無難。

```python
>>> range(1, 10)[::-1]  # 逆順に取得(実用的)
# range(9, 0, -1)
>>> tuple(range(1, 10)[::-1])
# (9, 8, 7, 6, 5, 4, 3, 2, 1)

>>> range(1, 10)[::-2]  # 偶数番目(0始まり数え)のみ抽出(これはまだマシ)
# range(9, 0, -2)
>>> tuple(range(1, 10)[::-2])
# (9, 7, 5, 3, 1)

>>> range(1, 10)[-2::-2]  # 奇数(0始まり数え)番目のみ抽出(-2番目を基準に逆順に2つ毎...ややこしい)
# range(8, 0, -2)
>>> tuple(range(1, 10)[-2::-2])
# (8, 6, 4, 2)
```

# **その他**

| 種類 | 概要 |
| :-- | :-- |
| [set](#set) | 集合 |
| [dict](#dict) | 辞書 |
| [bool](#bool) | 論理値(ブール値) |

## `set`

**集合**を扱う型。`セット`と読む。

### 書き方(インスタンスの作り方)

`{`と`}`とで囲うように書くと、`set`として認識される。
ただし、間に何も要素を書かない場合、**空集合ではなく[dict](#dict)と認識される**。

```python
>>> type({1})
# <class 'set'>
>>> {1}
# {1}

>>> type({})  # 要素が空だとdict扱い
# <class 'dict'>
```

空集合を作りたい時は、`set()`と書けばいい。

```python
>>> type(set())
# <class 'set'>

>>> set()
# set()
```

`{`と`}`の間に書いた要素は集合の要素として扱われる。
複数の要素を入れるときは、`,`を区切りとして書くことができる。
集合なので、重複する要素を指定しても1つだけ登録され、エラーにはならない。

```python
>>> {1, 2, 3}
# {1, 2, 3}

>>> {1, 2, 3, 2}  # 重複要素を渡しても1つしか入らない
# {1, 2, 3}
```

`,`の前後には空白スペースがいくつあっても問題ないが、慣例的に`,`の**前は空白なし**、**後ろは1つの空白を開けてから記述**が見通しがいいとされる。

```python
>>> {1   ,2.3, 45     }  # 適当に空白あっても認識する
# {1, 2.3, 45}

>>> {1, 2.3, 45}  # 慣例的にはこの書き方がよいとされる
# {1, 2.3, 45}
```

### 要素の取り出し

集合から要素を取り出すのは、`pop()`メソッドを使う。
`pop()`で取り出した要素は元の集合から削除される。
`set`に順序の概念はないので、取り出す順番の指定はできない。

```python
>>> s = {1, 2, 3}  # 先頭から要素を取り出す。
>>> s.pop()
# 1

>>> s  # 元の集合からは削除される
# {2, 3}
```

`for`ループで順次要素を取り出すこともできる。
この方法で取り出した場合は、元の集合もそのまま。

```python
>>> s = {1, 2, 3}
>>> for i in s:  # sを順次取得
...     print(i)
...
# 1
# 2
# 3

>>> s  # 取得後でもsはそのまま
{1, 2, 3}
```

### 要素の削除・追加

#### 単一要素の削除・追加

要素`elem`を削除したい時は、`remove(elem)`か`discard(elem)`を使う。
`remove(elem)`はelemが集合に含まれないとき`KeyError`となるが、`discard(elem)`は無視するという違いがある。
どちらを使うかは、シチュエーションによりけり。

```python
>>> s = {1, 2, 3}
>>> s.remove(2)  # 要素2を削除
>>> s
# {1, 3}

>>> s.remove(4)  # 存在しない要素の指定はエラー
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# KeyError: 4

>>> s = {1, 2, 3}
>>> s.discard(2)  # 存在する要素を指定した挙動はremoveと同じ
>>> s
# {1, 3}

>>> s.discard(4)  # 存在しない要素の指定でもエラーは出ない
# 何も起きない
```

集合に要素`elem`を追加するときは、`add(elem)`メソッドを使う。
要素`elem`が既に集合に含まれている場合は、単に無視される。

```python
>>> s = {1, 2, 3}
>>> s.add(4)  # 要素4を追加
>>> s
# {1, 2, 3, 4}

>>> s.add(2)  # 既存の要素を追加しても無視される
>>> s
{1, 2, 3, 4}
```

#### 複数要素の削除・追加

集合`A`に含まれる要素から、集合`B`,`C`に含まれる要素を除く場合は、`difference_update(*others)`メソッドを使う。
`*others`で与える集合は単数でも複数でもいい。

※ 数式やベン図でいうとこんな条件
$A \setminus (B \cup C)$
![差集合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291298/d6482c89-2065-1036-c546-2b9b5175576e.png)

```python
>>> a = {1, 2, 3}
>>> b = {3, 4, 5}
>>> c = {4, 5, 6}
>>> a.difference_update(b, c)  # 集合Aから集合B,Cに共通する要素を削除
>>> a
# {1, 2}

>>> b.difference_update(c)  # 渡す集合は1つでもいい
>>> b
# {3}
```

渡す集合は、集合といいつつ`set`でなくても[シーケンス型](#シーケンス型)なら受け付ける。
[int](#int)とかの単数オブジェクトはダメ。

```python
>>> a = {1, 2, 3}
>>> a.difference_update([2, 2, 3, 4, 5, 5])  # listでもいい
>>> a
# {1}

>>> a.difference_update(1)  # さすがにintはダメ
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: 'int' object is not iterable
```

集合`A`または`B`にのみ含まれる集合を取得したい場合は、`symmetric_difference_update(other)`メソッドを使う。
このメソッドでは、渡せる集合は1つだけ。
[シーケンス型](#シーケンス型)なら良いのと、[int](#int)などの単数形オブジェクトがダメなのは同じ。

※ 数式やベン図でいうとこんな条件
$(A \cap \overline{B}) \cup (\overline{A} \cap B)$
![排他的差集合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291298/be0ed6fe-183c-22a3-80fb-df2222bfd0c6.png)

```python
>>> a = {1, 2, 3}
>>> b = {2, 3, 4, 5}
>>> a.symmetric_difference_update(b)  # 集合AとBに共通しない要素のみを取得
>>> a
# {1, 4, 5}

>>> a = {1, 2, 3}
>>> a.symmetric_difference_update([2, 3, 4, 5])  # listでもいい
>>> a
# {1, 4, 5}
>>> a.symmetric_difference_update(1)  # intはダメ
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: 'int' object is not iterable
```

集合`A`と`B`,`C`に共通する要素のみを取得したい時は、`intersection_update(*others)`メソッドを使う。
`*others`は単数でも複数でもいい。
これも他のメソッド同様、[シーケンス型](#シーケンス型)なら受け付け、[int](#int)などの単数型はダメ。

※ 数式やベン図でいうとこんな条件
$A \cap B \cap C$
![共通集合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291298/89db480e-238a-6637-a33a-fce321b9995a.png)

```python
>>> a = {1, 2, 3}
>>> b = {3, 4, 5}
>>> c = {1 ,3, 5, 7, 9}
>>> a.intersection_update(b, c)  # 集合A,B,Cすべてに共通する要素のみ取得
>>> a
# {3}

>>> b.intersection_update(c)  # 渡す集合は1つでもいい
>>> b
# {3, 5}

>>> a = {1, 2, 3}
>>> a.intersection_update([1, 3, 5, 3, 1])  # listでもいい
>>> a
# {1, 3}

>>> a.intersection_update(1)  # intはダメ
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: 'int' object is not iterable
```

集合`A`と`B`,`C`いづれかに属する要素を取得したい時は、`update(*others)`メソッドを使う。
`*others`は単数でも複数でもいい。
これも他のメソッド同様、[シーケンス型](#シーケンス型)なら受け付け、[int](#int)などの単数型はダメ。

※ 数式やベン図でいうとこんな条件
$A \cup B \cup C$
![和集合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291298/a312a28e-aa60-7c2d-b4fc-90eb49483e93.png)

```python
>>> a = {1, 2, 3}
>>> b = {3, 4, 5}
>>> c = {1 ,3, 5, 7, 9}
>>> a.update(b, c)  # 集合AにBとCの要素を追加
>>> a
# {1, 2, 3, 4, 5, 7, 9}

>>> b.update(c)  # 渡す集合は1つでもいい
>>> b
# {1, 3, 4, 5, 7, 9}

>>> a = {1, 2, 3}
>>> a.update([3, 4, 5])  # listでもいい
>>> a
# {1, 2, 3, 4, 5}

>>> a.update(6)  # intはダメ
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: 'int' object is not iterable
```

### 他の型からの変換(キャスト)

[シーケンス型](#シーケンス型)から変換できる。
変換元の[シーケンス型](#シーケンス型)オブジェクトに、重複要素があっても1つだけに処理される。
[list](#list)とかで重複要素を削除するために、一旦`set`にして[list](#list)に戻すというのにも使える。

```python
>>> set([1, 2, 3])  # listから変換
# {1, 2, 3}

>>> set((1, 2, 3))  # tupleでもいい
# {1, 2, 3}

>>> set(range(10))  # rangeでもいい
# {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

>>> set([1, 2, 3, 2, 3])  # 元のオブジェクトに重複要素があってもいい
# {1, 2, 3}
```

[int](#int)などの単体オブジェクトだと、"1要素の集合"になるわけではなくエラーになる。

```python
>>> set(1)  # intはダメ
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: 'int' object is not iterable
```

## `dict`

**辞書**を扱う型。`ディクト`若しくは`ディクショナリ`と読む。
キーになる要素と値になる要素を組でもつことができ、任意の文字列や[tuple](#tuple)とも要素を対応付けられる。

### 書き方(インスタンスの作り方)

キー`k`と値要素`v`を、`{`と`}`とで囲うように`k:v`書くと、`dict`として認識される。
[set](#set)でも触れたが、例外的に`{}`と間に何も書かなければ空の`dict`になる。

```python
>>> type({"hoge":1})
# <class 'dict'>
>>> {"hoge":1}
# {'hoge': 1}

>>> type({})  # 空で書くとsetではなくdict認識
# <class 'dict'>
>>> {}
# {}
```

複数の要素を入れるときは、`,`を区切りとして書くことができる。
キーと要素は必ず必要なので、どちらかを省略するようなことはできない。

```python
>>> {'A': 1, 'B': 2, 'C': 3}
# {'A': 1, 'B': 2, 'C': 3}

>>> {'A': 1, 'B': , 'C': 3}  # キーのみの登録はできない
#   File "<stdin>", line 1
#     {'A': 1, 'B': , 'C': 3}
#                   ^
# SyntaxError: invalid syntax
>>> {'A': 1, : 2, 'C': 3}  # 要素のみの登録もできない
#   File "<stdin>", line 1
#     {'A': 1, : 2, 'C': 3}
#              ^
# SyntaxError: invalid syntax
```

`,`や`:`の前後には空白スペースがいくつあっても問題ないが、慣例的に`,`,`:`ともに**前は空白なし**、**後ろは1つの空白を開けてから記述**が見通しがいいとされる。

```python
>>> {  'A'   :1    ,  'B':2,  'C':   3     }  # 適当に空白あっても認識する
# {'A': 1, 'B': 2, 'C': 3}

>>> {'A': 1, 'B': 2, 'C': 3}  # 慣例的にはこの書き方がよいとされる
# {'A': 1, 'B': 2, 'C': 3}
```

### 特定要素の参照

#### 単一要素の参照

`dict`の要素にを参照するには、キー`k`を`dict`オブジェクトの末尾に`[k]`と記述して指定する。

```python
{'A': 1, 'B': 2, 'C': 3}
>>> a['B']
# 2
```

キーに無い要素を指定するとエラーになる。

```python
>>> a = {'A': 1, 'B': 2, 'C': 3}
>>> a['b']
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# KeyError: 'b'
```

`get(k, defalt)`メソッドでも、キー`k`で指定した要素を取得できる。
ただし、こちらはキーに無い要素を指定しても`default`の値を返し、エラーにならない。
`default`は省略可能で、省略すると`None`になる。

```python
>>> a = {'A': 1, 'B': 2, 'C': 3}
>>> a.get('B', 4)  # 存在するキーだと`['B']`で取得するのと同じ
# 2

>>> a.get('b', 4)  # 存在しないキーでもエラーにならない
# 4

>>> a.get('b')  # defaultを省略するとNone
# 出力なし
```

#### 複数要素の参照

`dict`に含まれるすべてのキーを取得する場合、`keys()`メソッドを使う。
これで戻ってくるのは、`dict_keys`というオブジェクトで、大本の`dict`の変化に追従する。

```python
>>> a = {'A': 1, 'B': 2, 'C': 3}
>>> b = a.keys()  # aのキー一式を取得
>>> b
# dict_keys(['A', 'B', 'C'])

>>> a.pop('A')  # aから'A'を削除
# 1
>>> a
{'B': 2, 'C': 3}
>>> b  # aで消したキー'A'がなくなっている
# dict_keys(['B', 'C'])
```

`dict`に含まれるすべての値を取得する場合、`values()`メソッドを使う。
これで戻ってくるのは、`dict_values`というオブジェクトで、大本の`dict`の変化に追従する。

```python
>>> a = {'A': 1, 'B': 2, 'C': 3}
>>> b = a.values()  # aの値一式を取得
>>> b
# dict_values([1, 2, 3])

>>> a.pop('A')  # a空'A'を削除
# 1
>>> a
# {'B': 2, 'C': 3}
>>> b  # aで消したキー'A'に対応した値1がなくなっている
# dict_values([2, 3])
```

`dict`に含まれるすべてのキーと値の組を取得する場合、`itemss()`メソッドを使う。
これで戻ってくるのは、`dict_items`というオブジェクトで、大本の`dict`の変化に追従する。

```python
>>> a = {'A': 1, 'B': 2, 'C': 3}
>>> b = a.items()  # aのキーと値の組一式を取得
>>> b
# dict_items([('A', 1), ('B', 2), ('C', 3)])

>>> a.pop('A')  # a空'A'を削除
# 1
>>> a
# {'B': 2, 'C': 3}
>>> b  # aで消したキー'A'と対応した値1の組がなくなっている
# dict_items([('B', 2), ('C', 3)])
```

`dict_keys()`,`dict_values()`,`dict_items()`ともに、大元の`dict`の変化に影響されたくないときは、[list](#list)や[tuple](#tuple)に変換すればいい。

```python
>>> a = {'A': 1, 'B': 2, 'C': 3}
>>> b = list(a.keys())  # listとして取得
>>> c = tuple(a.values())  # tupleとして取得
>>> d = list(a.items())  # listとして取得
>>> b
# ['A', 'B', 'C']
>>> c
# (1, 2, 3)
>>> d  # itemsの場合は、tupleのlistやtupleになる
# [('A', 1), ('B', 2), ('C', 3)]

>>> a.pop('A')  # aから'A'を削除
# 1
>>> a
# {'B': 2, 'C': 3}
>>> b  # aで消したキーもそのまま
# ['A', 'B', 'C']
>>> c  # aで消したキーもそのまま
# (1, 2, 3)
>>> d  # aで消したキーもそのまま
# [('A', 1), ('B', 2), ('C', 3)]
```

### 要素の削除・追加

キー`k`の要素を削除したい時は、`pop(k)`メソッドを使う。
削除とともに該当要素を返す。
存在しないキーを指定したらエラーになる。

```python
>>> a = {'A': 1, 'B': 2, 'C': 3}
>>> a.pop('A')  # 'A'の要素を削除
# 1
>>> a
# {'B': 2, 'C': 3}

>>> a.pop('a')  # 存在しないキーはエラー
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# KeyError: 'a'
```

ただし、`pop(k, default)`と指定すると、存在しないキーを指定したときに`default`の値が返ってくる。
当然、この場合はdictの中身は変化しない。

```python
>>> a = {'A': 1, 'B': 2, 'C': 3}
>>> a.pop('a', 4)  # 存在しないキーの時はdefault値
# 4
>>> a  # 元のdictは変化しない
# {'A': 1, 'B': 2, 'C': 3}
```

キー`k`の要素`v`を追加したい時は、`追加したいdict[k] = v`と記述すると追加される。
キー`k`が既に存在している場合は、そのキーに対応する値を`v`で上書きする。

```python
>>> a = {'A': 1, 'B': 2, 'C': 3}
>>> a
# {'A': 1, 'B': 2, 'C': 3}
>>> a['D'] = 4  # 新しくキー'D'で値4が追加される
>>> a
# {'A': 1, 'B': 2, 'C': 3, 'D': 4}

>>> a['B'] = 5  # 既存のキー'B'を指定すると、対応する値が2->5に上書きされる
>>> a
# {'A': 1, 'B': 5, 'C': 3, 'D': 4}
```

既存キーの場合に値を上書きしたくない場合は、`setdefault(k, default)`メソッドを使う。
`default`は省略可能で、省略すると`None`になる。

```python
>>> a = {'A': 1, 'B': 2, 'C': 3}
>>> a.setdefault('D', 4)  # 存在しないキーだとdefault値が追加される
# 4
>>> a
# {'A': 1, 'B': 2, 'C': 3, 'D': 4}
>>> a.setdefault('B', 5)  # 既存のキーだと既存の対応した値が返ってくる
# 2
>>> a  # dictも変化しない
# {'A': 1, 'B': 2, 'C': 3, 'D': 4}

>>> a.setdefault('E')  # 省略するとdefaultはNone
>>> a
# {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': None}
```

複数の値を一括して追加するときは、`update(other)`メソッドを使う。
`other`に既存のキーが含まれていると、`other`の値で上書きする。

```python
>>> a = {'A': 1, 'B': 2, 'C': 3}
>>> b = {'B': 4, 'D': 5}
>>> a.update(b)  # 'B'はaに既存なので2->4に上書き、'D'は存在しないので追加
>>> a
# {'A': 1, 'B': 4, 'C': 3, 'D': 5}
```

なお、`other`は1次元の要素数が`2`の2次元配列構造であれば、`dict`でなくてもいい。
この場合、1次元の要素は`キー, 値`として解釈される。

```python
>>> a = {'A': 1, 'B': 2, 'C': 3}
>>> b = (('B', 4), ('D', 5))  # tupleでもいい
>>> c = [('E', 6), ['F', 1]]  # listでもいいし、listとtupleが混ざっててもいい
>>> a.update(b)
>>> a
# {'A': 1, 'B': 4, 'C': 3, 'D': 5}
>>> a.update(c)
>>> a
# {'A': 1, 'B': 4, 'C': 3, 'D': 5, 'E': 6, 'F': 1}

>>> d = (('A', 2, 4), ('G', 9))  # 1次元の要素数が2でないとエラー
>>> a.update(d)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# ValueError: dictionary update sequence element #0 has length 3; 2 is required
```

## `bool`

**論理値(True or False)**を扱う型。`ブール`と読む。
明示的にはフラグ的な振る舞いをさせる変数に使うことが多いが、暗黙的にも各種条件演算の戻り値で頻繁に使っている。

### 書き方(インスタンスの作り方)

`True`,`False`と記述すると、`bool`として認識される。
名前の通り`True`は真、`False`は偽として扱われる。

```python
>>> type(True)
# <class 'bool'>
>>> True
# True

>>> type(False)
# <class 'bool'>
>>> False
# False
```

`bool()`と書いても`False`になる。
ただ、これは暗黙的に`None`を`bool`に変換した結果なので、`False`の生成が目的なら素直に`False`と書いたほうが良い。

```python
>>> bool()
# False
```

### 他の型からの変換

`bool`はすべての型から変換可能。
**↓↓↓19'9/9修正:コメントでご指摘いただきました。ありがとうございます。↓↓↓**
~~ただし、[数値型](#数値型)の`0`に相当する値と`None`以外は`True`となる。~~
ただし、[数値型](#数値型)の`0`に相当する値と`None`及び、空の[シーケンス型](#シーケンス型)と[dict](#dict)以外は`True`となる。

```python
>>> bool([])
# False
>>> bool([])
# False
>>> bool(())
# False
>>> bool(range(0))
# False
>>> bool(set())
# False
>>> bool({})
# False
```
**↑↑↑修正終わり↑↑↑**


```python
>>> bool(1)
# True
>>> bool(0)
# False

>>> bool(0.25)  # 少数でも0.0だけがFalse
# True
>>> bool(0.0)
# False

>>> bool(0+0j)  # 虚数でも0.0だけがFalse
# False
>>> bool(1j)  # 実部が0でも虚部が0でなければTrue
# True

>>> bool("0")  # 文字列だと0の文字でもTrue
# True
>>> bool("0.0")  # 少数表現でも同じ
# True
>>> bool([0])  # 要素が0だけのlistでもTrue
# True

>>> bool(None)  # NoneはFalse扱い
# False
```

# 参考

- [公式ドキュメント---組み込み型](https://docs.python.org/ja/3/library/stdtypes.html#built-in-types)