型とリテラル その2
前回は数学的な内容が辛かった分、
今回の学習はかなり楽でした。
以下、今回の備忘録です。
●3章 型とリテラル その2
■シーケンス(Sequence)
シーケンスはオブジェクトをシーケンシャル(順番)に処理するためのデータ構造。
Pythonのシーケンス
・コンテナ
・ジェネレータ
シーケンスがサポートしている操作
x in s
sの要素にxと同じ要素があればTrue。無ければFalseを返す。
>>> s = 'abc'
>>> s = 'abcdefg'
>>> 'c' in s
True
x not in s
sの要素にxと同じ要素があればFalse。無ければTrueを返す。
>>> 'z' not in s
True
s + t
sとtを連結する。
>>> s + 'h'
'abcdefgh'
s * n、 n * s
sをn回連結する。
>>> s
'abcdefg'
>>> s * 2
'abcdefgabcdefg'
>>> 2 * s
'abcdefgabcdefg'
s[i]
sのi番目の要素を取り出す。ゼロオリジン。
※ゼロオリジン・・・数字の0から始まる数え方のこと。
>>> s[0]
'a'
s[i:j]
sのi番目の要素からj番目の前までの要素を取り出す。
>>> s[1:4]
'bcd'
s[i:j:k]
sのi番目の要素からj番目の前までの要素をk個ごとに取り出す。
>>> s[0:6:2]
'ace'
len(s)
sの要素数を取り出す。
>>> len(s)
7
min(s)
sの要素のうち一番小さいものを取り出す。
>>> min(s)
'a'
max(s)
sの要素のうち一番大きいものを取り出す。
>>> max(s)
'g'
s.index(i)
sの要素の中にiと同じものが最初にあったインデックスを返す。
>>> s.index('c')
2
s.count(i)
sの要素の中にiと同じものがいくつあるかを返す。
>>> s2 = 'abcabcabc'
>>> s2.count('a')
3
■文字列/バイト列
Pythonの文字列はstr。
strは内部でUnicodeデータを保持する。
strは符号化されたテキストとして使う。
スクリプトファイル中のテキスト文字列はファイルのエンコーディングに従って
strオブジェクトをUnicodeに変換する。
python3はスクリプトファイルがUTF-8で記述していると想定する。
ファイルのエンコーディング指定
1行目、もしくはシェバン(shebang)がある時は
2行目に以下を記述。
# coding: UTF8
または
# coding=UTF8
Emacsの場合は
# -*- coding:UTF8 -*-
>>> x = 'テスト'.encode('UTF8')
>>> x.decode('UTF8')
'テスト'
UnicodeDecodeErrorを送出する。
>>> x.decode('cp932')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'cp932' codec can't decode byte 0x86 in position 2: illegal multibyte sequence
■イミュータブル
str型とbytes型は共にイミュータブル(変更不能)オブジェクト。
オブジェクト自身の状態を変更出来ない。
変数に割り当てているイミュータブルなオブジェクトの状態を変えるには、
新しいオブジェクトを作成して変数の指し示す先を新しいオブジェクトに変更する。
>>> s = 'spam'
>>> id(s)
139751185244264
>>> s = 'egg'
>>> id(s)
139751177393240
関数id()はオブジェクトの固有番号を返す。
■バイト配列型
バイト配列型 = バイト配列 = bytearray型
bytes型と違ってbytearray(バイト配列型)はミュータブルなバイト列。
違いはミュータブルであることだけ。
bytearrayはbytearrayコンストラクタで生成する。
bytearray(string, encoding[, errors])
※コンストラクタとは・・・オブジェクトの生成時に呼び出される特殊な関数。
初期化などをここで行う。
http://e-words.jp/w/E382B3E383B3E382B9E38388E383A9E382AFE382BF.html
>>> ba1 = bytearray()
>>> ba1.append(115)
>>> ba1.append(112)
>>> ba1.append(97)
>>> ba1.append(109)
>>> ba1
bytearray(b'spam')
bytearrayのその他の生成方法
・整数のイテレータを渡す
>>> ba2 = bytearray([115,112,97,109])
>>> ba2
bytearray(b'spam')
・文字列とそのエンコーディングを渡す
>>> ba3 = bytearray('日本語','UTF8')
>>> ba3
bytearray(b'\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e')
>>> ba3.decode('utf8')
'日本語'
・bytesを渡す
>>> ba4 = bytearray(b'egg')
>>> ba4
bytearray(b'egg')
・整数でサイズを指定して渡す
>>> ba5 = bytearray(128)
すべての要素が0で初期化される。
bytearrayの要素は0-255までの整数。
bytearrayからstrへの変換メソッドは
decode('utf8','strict')
もしくは
decode(encoding='utf8', errors='strict')
日本語の1文字は3バイトなので
bytearray型では「スパム」の要素数は9になる。
↓
>>> ba_nihongo = bytearray('スパム', 'utf8')
>>> ba_nihongo
bytearray(b'\xe3\x82\xb9\xe3\x83\x91\xe3\x83\xa0')
>>> len(ba_nihongo)
9
>>> ba_nihongo.decode('utf8','strict')
'スパム'
>>> len(ba_nihongo.decode('utf8','strict'))
3
errorsに指定可能なオプションは以下
strict・・・変換に失敗した際にUnicodeDecodeErrorを送出する。
ignore・・・問題のあるデータを無視する。
replace・・・問題のあるデータを「?」などの安全な文字に置換。
生成したbytearrayは要素を指定して値を変更出来る。
>>> ba = bytearray('spam', 'utf8')
>>> ba[1] = 104
>>> ba
bytearray(b'sham')
■リスト(lists)
順序を保ちながらオブジェクトをリストする。
種類を問わずに格納出来る。
数値・文字列・インスタンス・None・list・・・。
Pythonのリストはミュータブル(変更可能)。
>>> x = [1, 2, 3.0, "a", "b", "c"]
■インデクシング(シーケンス番号を使ったアクセス)
listのインデックスはゼロオリジン
"zero-based indexing"
(1オリジンの場合は"one-based")
>>> x[0]
1
>>> x[1]
2
>>> x[5]
'c'
範囲外の場合はIndexErrorを送出。
>>> x[6]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
ネガティブインデックス(負のインデックス)
>>> x[-1]
'c'
>>> [-2]
[-2]
>>> x[-2]
'b'
>>> x[-4]
3.0
>>> x[-6]
1
>>> x[-7]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
■スライス
listからサブリストを得る為のシンタックス。
※シンタックス・・・構文・構文規則
・インデックスかネガティブインデックスを使用する。
・開始位置から終了位置の一つ前までの要素を取り出す。
>>> x[1:2]
[2]
>>> x[1:4]
[2, 3.0, 'a']
>>> x[2:-1]
[3.0, 'a', 'b']
>>> x[-3:-1]
['a', 'b']
間違った順序や範囲外を指定すると
空のlistが返る。
>>> x[-1:-3]
>>> x[-3:-7]
スライスでは開始位置と終了位置を省略出来る。
>>> x[1:]
[2, 3.0, 'a', 'b', 'c']
>>> x[:3]
[1, 2, 3.0]
>>> x[:-2]
[1, 2, 3.0, 'a']
>>> x[:]
[1, 2, 3.0, 'a', 'b', 'c']
イテレーション・・・繰り返すこと。反復。
listは全要素に対して順に何らかの処理をする際に用いられる事が多い。
ループのシンタックスで全要素へ順にアクセス出来る。
>>> for item in x:
... print(item)
...
1
2
3.0
a
b
c
for inシンタックスのループ対象はlistであれば良い。
>>> x = [1, 2, 3.0, 'abc']
>>> for c in x[3]:
... print(c)
...
a
b
c
>>> for item in [1, 2, 3, 4]:
... print(item)
...
1
2
3
4
■リストの更新
要素をlistに追加するにはappendメソッドを使う。
>>> x =
>>> x.append("spam")
>>> x
['spam']
>>> x.append("eggs")
>>> x
['spam', 'eggs']
要素をlistから削除するにはremoveメソッドを使う。
>>> x.remove("eggs")
>>> x
['spam']
>>> x.remove("spam")
>>> x
要素がlistに無い場合はValueErrorを送出する。
>>> x.remove("abc")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list
インデックスを使ってlistの要素を変更する事が出来る。
>>> x = ["spam", "eggs"]
>>> x[1] = "hoge"
>>> x
スライスを使ったlistの変更
>>> x = [1, 2, 3, 4, 5]
>>> x[1:4]
[2, 3, 4]
スライスの範囲に右辺の要素を割り当てる。
>>> x[1:4] = ["spam", "eggs"]
>>> x
[1, 'spam', 'eggs', 5]
reverseメソッドで順序が反対になる。
>>> x.reverse()
>>> x
[3, 2, 1]
sortメソッドでソートする。
>>> x = [1, 0, 1, 7, 4, 1, 4, 7, 3, 3]
>>> x.sort()
>>> x
[0, 1, 1, 1, 3, 3, 4, 4, 7, 7]
▼考察
スライスは元のオブジェクトを変更しないけど
append、removeなどの
「メソッド」はオブジェクト自体を変更している。
■リスト内包表記(リストコンプリヘンション)
リスト内包表記はループと条件を使って新しいlistを生成する
特別なシンタックス。
リスト内包表記は通常のfor inループよりも高速。
>>> [i for i in range(10) if i % 2 == 0]
[0, 2, 4, 6, 8]
>>> [str(i) for i in range(10) if i % 2 == 0]
['0', '2', '4', '6', '8']
▼考察
[式 ループ 条件]という表記で、
条件に従いながらループ部分を繰り替えし、
ループの度に先頭の式を適用してからlistに追加している。
http://docs.python.jp/3.3/tutorial/datastructures.html
リスト内包表記は、括弧の中の式、for句、
そして0個以上のforかif句で構成されます。
ifだけじゃなくてforが後にくる事もある。
以下の2つは等価。
>>> [(x,y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
>>> combs = []
>>> for x in [1,2,3]:
... for y in [3,1,4]:
... if x != y:
... combs.append*1
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
■タプル(tuple)
タプルはイミュータブル(変更不可)なシーケンス型。
格納する値は自由。
要素が1つの場合はタプルであることがわかるように
末尾にカンマを付けて(1,)と記述する。
末尾のカンマで要素数が増えることはない。
listやdictもカンマを最後に付けることが可能。
インデックスでのアクセスが可能。
要素の変更は不可。
>>> x = (1,2,3,"a","b","c")
>>> x[0]
1
>>> x[3]
'a'
>>> x[3] = "z"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> y = (1)
>>> type(y)
<class 'int'>
>>> y = (1,)
>>> type(y)
<class 'tuple'>
■tupleの利点
listよりも処理が高速。
ハッシュ化が可能。
ハッシュ化が可能なので辞書型(dict)のキーに利用出来る。
※ハッシュ化・・・ハッシュ関数を用いてデータをある一定の値域にマッピングすること。
http://moguno.hatenablog.jp/entry/20110502/p1
■set(セット)
ユニークなオブジェクトの集合を保持するシーケンス。
同じオブジェクトの追加を無視する。
ハッシュ化出来ないものは追加出来ない。
>>> x = {1, 2, "a", "b"}
リストからの生成にはset関数を使う。
>>> x = set([1, 2, "a", "b"])
listはミュータブルなので格納出来ない。
>>> x = {[1, 2, 3], "abc"}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
tupleはイミュータブルなので格納出来る。
>>> x = {(1, 2, 3), "abc"}
■セットの操作
更新用のメソッド
・add
・remove
>>> x = {1, 3, "abc"}
>>> x.add(2)
>>> x
{3, 1, 2, 'abc'}
>>> x.remove(3)
>>> x
{1, 2, 'abc'}
存在しない場合はKeyError
>>> x.remove(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 5
discardを使えば要素が存在しなくてもエラーが出ない。
>>> x = {1, 2, 3, "abc"}
>>> x.discard(3)
>>> x
{1, 2, 'abc'}
>>> x.discard(5)
>>> x
{1, 2, 'abc'}
setはシーケンス型なのでイテレート処理をサポートしている。
ループでのイテレートが可能。
順番はサポートされない。
>>> x = {1, 2, 3, "abc"}
>>> for y in x:
... print(y)
...
3
1
2
abc
■setの利点
ユニオン・インターセクション・ディファレンスなどの処理で
高速に動作する。
■ユニオン(Union合併)
setの合併
>>> store1 = {7, 9, 2}
>>> store2 = {18, 22, 3, 7, 12}
>>> store1.union(store2)
{2, 3, 7, 9, 12, 18, 22}
3つ以上の合併はコンマの後に引数を増やす。
>>> store3 = {11, 6, 9, 15}
>>> store1.union(store2,store3)
{2, 3, 6, 7, 9, 11, 12, 15, 18, 22}
■インターセクション(交差・積集合)
2つのsetに含まれる要素を抽出。
>>> store1 = {7, 9, 2}
>>> store2 = {18, 22, 3, 7, 12}
>>> store1.intersection(store2)
{7}
3つ以上の場合は引数を増やす。
>>> store1 = {7, 9, 2}
>>> store2 = {18, 22, 3, 7, 12, 9}
>>> store3 = {11, 7, 3, 6, 9, 15}
>>> store1.intersection(store2,store3)
{9, 7}
■ディファレンス(Difference 差集合)
ディファレンスは元の集合のみに存在し、
他の集合には存在しない部分。
元になる集合に意味を持つ。
>>> store1 = {7, 9, 2}
>>> store2 = {18, 22, 3, 7, 12, 9}
>>> store1.difference(store2)
{2}
順番を変えてみる
>>> store2.difference(store1)
{18, 3, 12, 22}
3つ以上の場合は引数を増やす。
>>> store1 = {18, 22, 3, 7, 12, 9}
>>> store2 = {7, 9, 2}
>>> store3 = {11, 7, 3, 6, 9, 15}
>>> store1.difference(store2,store3)
{18, 12, 22}
どちらかの集合にだけ含まれる要素を抽出。
順番は関係ない。
>>> store1 = {18, 22, 3, 7, 12, 9}
>>> store2 = {7, 9, 2}
>>> store1.symmetric_difference(store2)
{2, 3, 12, 18, 22}
>>> store2.symmetric_difference(store1)
{18, 3, 22, 12, 2}
>>> (store1.symmetric_difference(store2) == store2.symmetric_difference(store1))
True
■サブセット・スーパーサブセットとディスジョイントセット(素集合)
セットAにセットBの要素が全て含まれている場合、
・セットAはセットBのスーパーセット。
・セットBはセットAのサブセット。
>>> colors = {"red","blue","green","yellow","purple","orange"}
>>> subset = {"purple","green"}
>>> subset.issubset(colors)
True
>>> colors.issuperset(subset)
True
1つも共通の要素が含まれないセットの事を
ディスジョイント(素集合)という。
2つのセットがディスジョイントかどうかは
isdisjointメソッドで確認する。
>>> primary = {"red","blue","green"}
>>> art_primary = {"magenta","cyan","yellow"}
>>> primary.isdisjoint(art_primary)
True
■辞書型(Dictionaries)
キーと値を対応させたデータ型をマップ型と呼ぶ。
リスト・タプル・インスタンス・他の辞書型オブジェクト・etc・・・
Pythonのオブジェクトならどんなものでも格納出来る。
順番はサポートしていない。
>>> d = {
... 'key1': 'Value1',
... 'key2': 'Value2',
... 'key3': 'Value3',
... }
>>> d
{'key3': 'Value3', 'key2': 'Value2', 'key1': 'Value1'}
行をわけなくても作成出来る・・・。
>>> d2 = {'key1': 'Value1', 'key2': 'Value2',}
>>> d2
{'key2': 'Value2', 'key1': 'Value1'}
■インデックスアクセス
キーを使って値を取り出せる。
>>> d['key1']
'Value1'
>>> d['key2']
'Value2'
>>> d['key4']
存在しないキーを使うとKeyError
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'key4'
in構文で辞書にキーが登録されているか確認出来る。
これで確認しておけばKeyErrorを回避出来る。
>>> 'key1' in d
True
>>> 'key4' in d
False
getメソッド
キーが登録されていない場合に
第2引数をデフォルト値として使用出来る。
指定が無い場合はNone(非表示)が返る。
>>> d.get('key1')
'Value1'
>>> d.get('key4')
>>> d.get('key4')
>>> d.get('key4', 'default')
'default'
>>> a = d.get('key4')
>>> a is None
True
>>> value = d.get('key4')
>>> if value:
... print(value)
... else:
... print("key4 does not exist!")
...
key4 does not exist!
■イテレーションアクセス
辞書の全ての要素をイテレーションするには、
inシンタックスでfor x in yのようにすると
すべてのキーをイテレート出来る。
>>> for key in d:
... print(key)
...
key2
key3
key1
値をイテレートするにはvaluesメソッドを使う。
>>> for value in d.values():
... print(value)
...
Value2
Value3
Value1
値とキーの両方をイテレートするにはitemsメソッドを使う。
>>> for key, value in d.items():
... print(key, value)
...
key2 Value2
key3 Value3
key1 Value1
■辞書の更新
※アサイン・・・割り当てる。
・既存の値を変更
インデックスを指定してアサインする。
>>> d['key1'] = 'NewValue1'
>>> d['key1']
・キーと値を追加
新しいキーでアサインする。
'NewValue1'
>>> d['newkey'] = 'NewValue1'
>>> d
{'newkey': 'NewValue1', 'key2': 'Value2', 'key3': 'Value3', 'key1': 'NewValue1'}
delメソッド・・・キーと値の削除を行う。
>>> del d['newkey']
>>> d
{'key2': 'Value2', 'key3': 'Value3', 'key1': 'NewValue1'}
popメソッド・・・値を取り出しつつ、キーと値の削除を行う。
>>> d.pop('key2')
'Value2'
>>> d
{'key3': 'Value3', 'key1': 'NewValue1'}
popメソッドはデフォルト値を指定するとエラーを出さずに処理を行う。
>>> d.pop('key2', 'default')
'default'
辞書型の削除はpopメソッドにデフォルト値を設定して行った方が
エラーを出さなくて済むので便利。
■辞書の順序
辞書型は順序が保証されない。
順序が重要な際はOrderedDictを使う。
>>> from collections import OrderedDict
>>> od = OrderedDict()
>>> od['b'] = 1
>>> od['1'] = 2
>>> od['a'] = 3
>>> for k, v in od.items():
... print('{}:{}'.format(k, v))
...
b:1
1:2
a:3
>>> od
OrderedDict([('b', 1), ('1', 2), ('a', 3)])
■None型
値が存在しない場合やアンセットしたことを明示する場合に利用する。
>>> d = {'key1': 'Value1', 'key2': 'Value2'}
>>> user_key = input("Key: ")
Key: key1
>>> value = d.get(user_key, None)
>>> print(value)
Value1
>>> user_key = input("Key: ")
Key:
>>> value = d.get(user_key, None)
>>> print(value)
None
Noneは常に偽として評価される。
>>> if None:
... print('None is true!')
... else:
... print('None is false!')
...
None is false!
Noneなのか偽なのか確認したい場合にはisを使う。
>>> y = None
>>> if y is None:
... print("y is None")
...
y is None
FalseがNoneではなく偽。
>>> y = False
>>> if y is None:
... print("y is None")
... else:
... print("y is not None")
...
y is not None
パーフェクトPython (PERFECT SERIES 5)
- 作者: Pythonサポーターズ
- 出版社/メーカー: 技術評論社
- 発売日: 2013/03/05
- メディア: 大型本
- 購入: 1人 クリック: 65回
- この商品を含むブログ (17件) を見る
*1:x, y