概要
普段使いする中で、よく使う組み込み型を紹介する。
全部でなく抜粋なので、詳細が気になる人は公式ドキュメントも参照。
対象
-
Python
の初歩中の初歩を学習したい人
執筆時の環境
- OS: Windows10
- Python: 3.7.3
本記事中の定義
実行例中の定義
>>> "Pythonインタプリタでの実行コマンド"
# 上のコマンドに対応するターミナルの表示
用語定義
- リテラル:代数を使わずに書いた数値や文字列。いわゆるべた書き。
- ネスト:入れ子構造のこと。
- キャスト:元の型から別の型に変換すること。
紹介する型一覧
数値型
種類 | 概要 |
---|---|
int | 整数 |
float | 浮動小数 |
complex | 複素数 |
int
整数値を扱う型。イント
と読む。
表現可能な範囲は、環境のシステムに依存する。
他の言語ではより広範囲を扱うlong
などがあるが、Python3の場合はすべてint
が包括する(Python2にはlong
も存在する)。
リテラル値の書き方
数字だけの連続した記述はint
として扱われる。
>>> type(123)
# <class 'int'>
他の型からの変換(キャスト)
>>> int(123.0)
# 123
>>> int("123")
# 123
少数の小数部は四捨五入ではなく切り捨て。
>>> int(123.9)
# 123
文字列からの変換は整数値の文字列のみ対応。
少数値の文字列や、数値でない文字列からは変換できない.
>>> 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以上)
>>> int(" 123 ") # 前後に空白スペース
# 123
>>> int("-123") # 先頭に+/-符号
# -123
>>> int("123_456") # 桁間にアンダースコア
# 123456
float
浮動少数を扱う型。フロート
と読む。
表現可能な範囲は、環境のシステムに依存する。
他言語ではdouble
などがあるが、pythonではfloat
がすべて包括する。
リテラル値の書き方
連続する数字と1つの.
(ドット)で記述した値は、float
として扱われる。
>>> type(123.4)
# <class 'float'>
e
若しくはE
を$10^n$の意味として書くこともできる。
この記述では、小数点以下が結果的に0
になる値でも整数にはならない。
>>> 1e3
# 1000.0
>>> type(1e3)
# <class 'float'>
>>> 1E3 # 大文字でもいい
# 1000.0
他の型からの変換(キャスト)
>>> float(123)
# 123.0
>>> float("123.0")
# 123.0
文字列からの変換は、整数値文字列でも問題ない。
>>> float("123") # 整数値文字列
# 123.0
数値ではない文字列は変換不能だが、次の4パターンに限り変換可能。
- 数値以外に空白スペースのみが含まれる文字列
- 数値文字列の先頭につく
+/-
符号文字 - 数値文字列の桁間に含まれるアンダースコア(バージョン3.6以上)
- 数値文字列に含まれる指数表記用の
e
,E
>>> 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$と非数**を作ることができる。
>>> float("infinity") # "infinity"で無限大
# inf
>>> float("inf") # "inf"でもいい
# inf
>>> float("-inf") # 負の無限大も可能
# -inf
>>> float("INF") # 大文字/小文字は問わない
# inf
>>> float("nan") # "nan"で非数
# nan
>>> float("NAN") # 大文字/小文字は問わない
# nan
complex
複素数を扱う型。コンプレックス
と読む。
実部と虚部を別々に管理できる。
電子回路設計の支援アプリなんかで、インピーダンスの計算する時とか便利。
リテラル値の書き方
リテラルの数値の末尾にj
若しくはJ
をつけるとcomplex
として扱われる。
j
をつけた数値は虚部として使われる。
>>> type(2j) # 整数リテラル
# <class 'complex'>
>>> type(2.3j) # 少数リテラル
# <class 'complex'>
>>> type(2.3J) # Jは大文字でもよい
# <class 'complex'>
リテラルで実部ごと書くときは、普通に+
/-
でつなぐだけ。
>>> 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
を末尾につける。
>>> x = 1.2+3.4j
>>> x.real # 実部だけ取り出す
# 1.2
>>> x.imag # 虚部だけ取り出す
# 3.4
取り出された値の型はcomplex
ではなく、floatになる。
>>> x = 1.2+3.4j
>>> type(x)
# <class 'complex'>
>>> type(x.real)
# <class 'float'>
>>> type(x.imag)
# <class 'float'>
>>> x = 1+2j
# <class 'complex'>
>>> type(x.real)
# <class 'float'>
>>> type(x.imag)
# <class 'float'>
complex(実部, 虚部)
としてインスタンスを作ることもできる。
>>> complex(1.2, 3.4)
# (1.2+3.4j)
虚部を省略して書いた場合でも、虚部が0j
のcomplex
が返ってくる。
>>> complex(1.2)
# (1.2+0j)
他の型からの変換(キャスト)
文字列から変換できる。
>>> complex("1.2+3j")
# (1.2+3j)
>>> complex("1.2-3j") # 実部と虚部の間は'-'でもいい
# (1.2-3j)
虚部を負数にしたい時に"実数+-虚数"
という記述はエラーになる。
>>> complex("1.2+-3j")
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# ValueError: complex() arg is a malformed string
各部の数値と+
/-
符号の間に空白スペースがあってはいけない。
>>> complex("1.2 + 3j")
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# ValueError: complex() arg is a malformed string
str->float変換で、例外的に変換できるパターンは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
文字列を扱う型。ストリング
若しくはストラ
と読む。
他言語では"単一文字はchar
など"の場合があるが、pythonでは文字と文字列の区別はなく、str
がすべて包括する。
リテラル値の書き方
"
(ダブルクォーテーション)若しくは'
(シングルクォーテーション)で囲んだ範囲はstr
として扱われる。
>>> type("abcd")
# <class 'str'>
>>> type('abcd') # `'`でも同じ
# <class 'str'>
"
/'
どちらでもリテラル文字列の範囲を表すが、始めと終わりの記号は統一でないといけない。
>>> type("abcd') # 始めが`"`,終わりが`'`
File "<stdin>", line 1
type("abcd')
^
SyntaxError: EOL while scanning string literal
2つの記号をネストして囲うことは可能。
その場合は、内側の記号は文字列の1部とみなされる。
>>> type("ab'cd'ef")
# <class 'str'>
>>> "ab'cd'ef" # `'`が文字列の1部
# "ab'cd'ef"
>>> 'ab"cd"ef' # `"`が文字列の1部
# 'ab"cd"ef'
"
/'
を文字列の1部に含みたい場合は、\
(バックスラッシュ)でエスケープして文字列中に入れる。
>>> "ab\"cd\"ef\"gh"
# 'ab"cd"ef"gh'
>>> 'ab\'cd\'ef\'gh'
# "ab'cd'ef'gh"
\
を純粋に含めた文字列としたい場合は、リテラル文字列の接頭辞にr
をつければいい。
標準で\
をデリミタに使っている、Windows系のパスとかを扱うときに、知っていると重宝する。
>>> "C:\WorkSpace\tmp\hoge.txt" # `\t`がタブとして解釈されている
# 'C:\\WorkSpace\tmp\\hoge.txt'
>>> r"C:\WorkSpace\tmp\hoge.txt" # すべての`\`がエスケープされている
# 'C:\\WorkSpace\\tmp\\hoge.txt'
他の型からの変換(キャスト)
str
は基本的に変換できないオブジェクトはない。
>>> str(10)
# '10'
>>> str(1.23)
# '1.23'
>>> str([1, 2, 3])
# `[1, 2, 3]`
ただし、変換される形式がどうであるかはまちまち。
__str__()
,__repr__()
メソッドを未定義のクラスの場合は、インスタンスのIDが表示される。
>>> class Hoge:
... pass
...
>>> str(Hoge())
# '<__main__.Hoge object at 0x00000123456789AB>'
__str__
メソッドをオーバーライドすれば、任意の形式にできるので、特に問題ではない。
>>> class Hoge:
... def __str__(self):
... return "hoge"
...
>>> str(Hoge())
# 'hoge'
シーケンス型
種類 | 概要 |
---|---|
list | 変更可能な配列 |
tuple | 変更不能な配列 |
range | 規則的な数値範囲の配列 |
list
内容が変更可能(ミュータブルな配列を扱う型。リスト
と読む。
要素の挿入・削除やソートといった機能のメソッドも持っている。
書き方(インスタンスの作り方)
[
と]
とで囲うように書くと、list
として認識される。
>>> type([])
# <class 'list'>
>>> []
# []
[
と]
の間に書いた要素はリストの要素として扱われる。
複数の要素を入れるときは、,
を区切りとして書くことができる。
他言語では、"配列の要素の型"を統一しないといけないのもあるが、pythonの場合は異なる型でも同じ配列にできる。
>>> [1,2,3]
# [1, 2, 3]
>>> [1,2.3,"45"] # 要素の型は統一しなくてもいい
# [1, 2.3, '45']
,
の前後には空白スペースがいくつあっても問題ないが、慣例的に,
の前は空白なし、後ろは1つの空白を開けてから記述が見通しがいいとされる。
>>> [1 ,2.3, 45 ] # 適当に空白あっても認識する
# [1, 2.3, 45]
>>> [1, 2.3, 45] # 慣例的にはこの書き方がよいとされる
# [1, 2.3, 45]
空のリストを作る時はlist()
で作ってもいい。
名前がズバリなので、こっちのほうが見通しはいい感じもするが、タイプ数的には[]
のほうが楽なのでどちらがいいかは好みによる。
>>> []
# []
>>> list() # これでも同じ
# []
多次元配列はlist
にlist
を入れる。
>>> [[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
の要素数が違っても問題ない。
>>> [[1, 2], [3, 4, 5]] # 0番目の要素は2つ、1番目(0始まり)の要素は3つ
# [[1, 2], [3, 4, 5]]
特定要素の参照・追加
list
の要素参照方法は、tupleやrangeの要素参照方法と全く同じなので、それらを読んでいるなら読み飛ばして問題ない。
単一要素の参照
list
型のオブジェクトの末尾に、[参照したい要素のインデックス]
をつければ、その要素を参照できる。
なお、インデックスは先頭を0
として数える。
>>> [1, 2, 3][0]
# 1
>>> [1, 2, 3][1]
# 2
list
の要素数を超えたインデックスの指定はできない。
>>> [1, 2, 3][100]
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# IndexError: list index out of range
インデックスを負数で表すと末尾から逆順に参照できる。
ただし、末尾からの場合は-1
から数える。
任意要素の参照という目的より、"要素数不定のlist
で末尾要素を取りたい"というシチュエーションで重宝する。
>>> [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
番目の要素は含まれない。
>>> [1, 2, 3, 4, 5][1:4]
# [2, 3, 4]
j
=i
+1だと取得する要素は1つだが、[i]
とは違い要素が1つのlist
が返ってくる。
>>> [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
が返ってくる。
>>> [1, 2, 3, 4, 5][2:2] # iとjが等しい場合
# []
>>> [1, 2, 3, 4, 5][3:1] # i>jの場合
# []
i
番目から末尾までの指定は[i:]
と省略して表記できる。
同様に、先頭からj
番目までの指定は[:j]
と表記できる。
>>> [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
個分"という指定をしたい時は、直観的にもわかりやすいので例外的に使ってもいいと思う。
>>> [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
の倍数毎に抽出した配列"を取得するのに便利(偶数番目要素と奇数番目要素への仕分けなど)
>>> [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
を取得する"程度の使い方にとどめるのが無難。
>>> [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
を追加できる。
>>> 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
は逆順指定でもいい。
>>> 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
番目までは元の順序で、それ以降は逆順"という処理をトリッキーに書けたりするが、どちらにしても可読性はよくないので控えたほうがいい。
>>> hoge = [1, 2, 3]
>>> hoge.insert(100, 4) # 上の行でhogeが3要素であることを認識していないと、"10番目(0始まり)に挿入したい"という意図に見える
>>> hoge
# [1, 2, 3, 4]
>>> hoge = [1, 2, 3]
>>> hoge.append(4) # この行だけで"末尾に追加したい"という意図がわかる
複数要素の追加
extend(x)
メソッドで、末尾にシーケンス型オブジェクトx
に含まれる全要素を追加できる。
>>> hoge = [1, 2, 3]
>>> hoge
# [1, 2, 3]
>>> hoge.extend([4, 5]) # 末尾に4, 5を追加
>>> hoge
# [1, 2, 3, 4, 5]
x
がシーケンス型のオブジェクト以外だとエラーになる。
>>> 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
は逆順指定でもいい。
>>> 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
メソッド同様、可読性はよくないので控えたほうがいい。
>>> hoge = [1, 2, 3]
>>> hoge[10:10] = [4, 5] # 上の行でhogeが3要素であることを認識していないと、"10番目(0始まり)に挿入したい"という意図に見える
>>> hoge
# [1, 2, 3, 4, 5]
>>> hoge = [1, 2, 3]
>>> hoge.extend([4, 5]) # この行だけで"末尾に追加したい"という意図がわかる
>>> hoge
# [1, 2, 3, 4, 5]
tuple
内容が変更不可能(イミュータブル)な配列を扱う型。タプル
と読む。
書き方(インスタンスの作り方)
(
と)
とで囲うように書くと、tuple
として認識される。
>>> type(())
# <class 'tuple'>
>>> ()
# ()
↓↓↓19'9/9修正:コメントでご指摘いただきました。ありがとうございます。↓↓↓
(
と)
の間に書いた要素はtuple
の要素として扱われる。
複数の要素を入れるときは、,
を区切りとして書く。
,
で繋いだ複数の要素はtuple
として認識される。
>>> a = 1, 2, 3
>>> type(a)
# <class 'tuple'>
↑↑↑修正終わり↑↑↑
他言語では、"配列の要素の型"を統一しないといけないのもあるが、pythonの場合は異なる型でも同じ配列にできる。
>>> (1,2,3)
# (1, 2, 3)
>>> (1,2.3,"45") # 要素の型は統一しなくてもいい
# (1, 2.3, '45')
list同様、,
の前後には空白スペースがいくつあっても問題ないが、慣例的に,
の前は空白なし、後ろは1つの空白を開けてから記述が見通しがいいとされる。
>>> (1 ,2.3, 45 ) # 適当に空白あっても認識する
# (1, 2.3, 45)
>>> (1, 2.3, 45) # 慣例的にはこの書き方がよいとされる
# (1, 2.3, 45)
listは要素が1つなら,
があっても無くてもlistとして認識されたが、tuple
の場合は要素が1つでも,
をつけないと、その要素の型で認識されてしまう。
>>> [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と違い変更できないので、(たぶん)使い道はない。
>>> tuple()
# ()
多次元配列はtuple
にtuple
を入れる。
>>> ((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
の要素数が違っても問題ない。
>>> ((1, 2), (3, 4, 5)) # 0番目の要素は2つ、1番目(0始まり)の要素は3つ
((1, 2), (3, 4, 5))
特定要素の参照
tuple
の要素参照方法は、listやrangeの要素参照方法と全く同じなので、それらを読んでいるなら読み飛ばして問題ない。
(順番に読んでいる人 -> 次へ)
単一要素の参照
tuple
型のオブジェクトの末尾に、[参照したい要素のインデックス]
をつければ、その要素を参照できる。
なお、インデックスは先頭を0
として数える。
>>> (1, 2, 3)[0]
# 1
>>> (1, 2, 3)[1]
# 2
tuple
の要素数を超えたインデックスの指定はできない。
>>> (1, 2, 3)[100]
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# IndexError: tuple index out of range
インデックスを負数で表すと末尾から逆順に参照できる。
ただし、末尾からの場合は-1
から数える。
任意要素の参照という目的より、"要素数不定のtuple
で末尾要素を取りたい"というシチュエーションで重宝する。
>>> (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
番目の要素は含まれない。
>>> (1, 2, 3, 4, 5)[1:4]
# (2, 3, 4)
j
=i
+1だと取得する要素は1つだが、[i]
とは違い要素が1つのtuple
が返ってくる。
>>> (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
が返ってくる。
>>> (1, 2, 3, 4, 5)[2:2] # iとjが等しい場合
# ()
>>> (1, 2, 3, 4, 5)[3:1] # i>jの場合
# ()
i
番目から末尾までの指定は[i:]
と省略して表記できる。
同様に、先頭からj
番目までの指定は[:j]
と表記できる。
>>> (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
個分"という指定をしたい時は、直観的にもわかりやすいので例外的に使ってもいいと思う。
>>> (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
の倍数毎に抽出した配列"を取得するのに便利(偶数番目要素と奇数番目要素への仕分けなど)
>>> (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
を取得する"程度の使い方にとどめるのが無難。
>>> (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やtupleで同様の配列を作るより、"広範囲の配列を短い構文で定義"でき、"所要するメモリも少ない"。
なお、range
は出力の見た目がわかりにくいので、実行例にはtupleに変換した出力を併記しておく。
書き方(インスタンスの作り方)
range(stop)
で0
から整数stop
までのrange
が作成できる。
要素にstop
は含まれない。
>>> 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
は含まない。
>>> range(5, 10) # 5から10で作る
# range(5, 10)
>>> tuple(range(5, 10))
# (5, 6, 7, 8, 9)
start
,stop
は負数でもいい。
>>> 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
の場合でも作成はできる。
ただし、"要素は空"の扱いになる。
>>> 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
毎"として作成できる。
>>> 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
だと"要素が空"の扱いになる。
>>> 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以外の型は使えない。
たとえ、"少数部が0
のfloat"や"整数文字列のstr"だとしてもエラーになる。
>>> 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やtupleの要素参照方法と全く同じなので、それらを読んでいるなら読み飛ばして問題ない。
(順番に読んでいる人 -> 次へ)
単一要素の参照
range
型のオブジェクトの末尾に、[参照したい要素のインデックス]
をつければ、その要素を参照できる。
なお、インデックスは先頭を0
として数える。
>>> range(1, 10)[0]
# 1
>>> range(1, 10)[5]
# 6
range
の要素数を超えたインデックスの指定はできない。
>>> range(1, 10)[100]
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# IndexError: range object index out of range
インデックスを負数で表すと末尾から逆順に参照できる。
ただし、末尾からの場合は-1
から数える。
>>> 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
番目の要素は含まれない。
>>> range(1, 10)[1:4]
# range(2, 5)
>>> tuple(range(1, 10)[1:4])
# (2, 3, 4)
j
=i
+1だと取得する要素は1つだが、[i]
とは違い要素が1つのrange
が返ってくる。
>>> 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
が返ってくる。
>>> 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]
と表記できる。
>>> 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
個分"という指定をしたい時は、直観的にもわかりやすいので例外的に使ってもいいと思う。
>>> 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
の倍数毎に抽出した配列"を取得するのに便利(偶数番目要素と奇数番目要素への仕分けなど)
>>> 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
を取得する"程度の使い方にとどめるのが無難。
>>> 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 | 集合 |
dict | 辞書 |
bool | 論理値(ブール値) |
set
集合を扱う型。セット
と読む。
書き方(インスタンスの作り方)
{
と}
とで囲うように書くと、set
として認識される。
ただし、間に何も要素を書かない場合、空集合ではなくdictと認識される。
>>> type({1})
# <class 'set'>
>>> {1}
# {1}
>>> type({}) # 要素が空だとdict扱い
# <class 'dict'>
空集合を作りたい時は、set()
と書けばいい。
>>> type(set())
# <class 'set'>
>>> set()
# set()
{
と}
の間に書いた要素は集合の要素として扱われる。
複数の要素を入れるときは、,
を区切りとして書くことができる。
集合なので、重複する要素を指定しても1つだけ登録され、エラーにはならない。
>>> {1, 2, 3}
# {1, 2, 3}
>>> {1, 2, 3, 2} # 重複要素を渡しても1つしか入らない
# {1, 2, 3}
,
の前後には空白スペースがいくつあっても問題ないが、慣例的に,
の前は空白なし、後ろは1つの空白を開けてから記述が見通しがいいとされる。
>>> {1 ,2.3, 45 } # 適当に空白あっても認識する
# {1, 2.3, 45}
>>> {1, 2.3, 45} # 慣例的にはこの書き方がよいとされる
# {1, 2.3, 45}
要素の取り出し
集合から要素を取り出すのは、pop()
メソッドを使う。
pop()
で取り出した要素は元の集合から削除される。
set
に順序の概念はないので、取り出す順番の指定はできない。
>>> s = {1, 2, 3} # 先頭から要素を取り出す。
>>> s.pop()
# 1
>>> s # 元の集合からは削除される
# {2, 3}
for
ループで順次要素を取り出すこともできる。
この方法で取り出した場合は、元の集合もそのまま。
>>> 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)
は無視するという違いがある。
どちらを使うかは、シチュエーションによりけり。
>>> 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
が既に集合に含まれている場合は、単に無視される。
>>> 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)$
>>> 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とかの単数オブジェクトはダメ。
>>> 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などの単数形オブジェクトがダメなのは同じ。
※ 数式やベン図でいうとこんな条件
$(A \cap \overline{B}) \cup (\overline{A} \cap B)$
>>> 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などの単数型はダメ。
※ 数式やベン図でいうとこんな条件
$A \cap B \cap C$
>>> 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などの単数型はダメ。
※ 数式やベン図でいうとこんな条件
$A \cup B \cup C$
>>> 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とかで重複要素を削除するために、一旦set
にしてlistに戻すというのにも使える。
>>> 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などの単体オブジェクトだと、"1要素の集合"になるわけではなくエラーになる。
>>> set(1) # intはダメ
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# TypeError: 'int' object is not iterable
dict
辞書を扱う型。ディクト
若しくはディクショナリ
と読む。
キーになる要素と値になる要素を組でもつことができ、任意の文字列やtupleとも要素を対応付けられる。
書き方(インスタンスの作り方)
キーk
と値要素v
を、{
と}
とで囲うようにk:v
書くと、dict
として認識される。
setでも触れたが、例外的に{}
と間に何も書かなければ空のdict
になる。
>>> type({"hoge":1})
# <class 'dict'>
>>> {"hoge":1}
# {'hoge': 1}
>>> type({}) # 空で書くとsetではなくdict認識
# <class 'dict'>
>>> {}
# {}
複数の要素を入れるときは、,
を区切りとして書くことができる。
キーと要素は必ず必要なので、どちらかを省略するようなことはできない。
>>> {'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つの空白を開けてから記述が見通しがいいとされる。
>>> { '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]
と記述して指定する。
{'A': 1, 'B': 2, 'C': 3}
>>> a['B']
# 2
キーに無い要素を指定するとエラーになる。
>>> 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
になる。
>>> 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
の変化に追従する。
>>> 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
の変化に追従する。
>>> 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
の変化に追従する。
>>> 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やtupleに変換すればいい。
>>> 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)
メソッドを使う。
削除とともに該当要素を返す。
存在しないキーを指定したらエラーになる。
>>> 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の中身は変化しない。
>>> 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
で上書きする。
>>> 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
になる。
>>> 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
の値で上書きする。
>>> 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次元の要素はキー, 値
として解釈される。
>>> 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
は偽として扱われる。
>>> type(True)
# <class 'bool'>
>>> True
# True
>>> type(False)
# <class 'bool'>
>>> False
# False
bool()
と書いてもFalse
になる。
ただ、これは暗黙的にNone
をbool
に変換した結果なので、False
の生成が目的なら素直にFalse
と書いたほうが良い。
>>> bool()
# False
他の型からの変換
bool
はすべての型から変換可能。
↓↓↓19'9/9修正:コメントでご指摘いただきました。ありがとうございます。↓↓↓
ただし、数値型の0
に相当する値とNone
以外はTrue
となる。
ただし、数値型の0
に相当する値とNone
及び、空のシーケンス型とdict以外はTrue
となる。
>>> bool([])
# False
>>> bool([])
# False
>>> bool(())
# False
>>> bool(range(0))
# False
>>> bool(set())
# False
>>> bool({})
# False
↑↑↑修正終わり↑↑↑
>>> 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