Python習得中 – その3 このエントリーをはてなブックマークに追加

3章まで読了。データ構造を表す型が何気に豊富ですね…。

リストをコピーする方法が 3通りもある

意外と自由度高いな…。

>>> a = [1, 2, 3]
>>> b = a.copy()
>>> c = list(a)
>>> d = a[:]
>>> a[0] = 'hoge'
>>> a
['hoge', 2, 3]
>>> b
[1, 2, 3]
>>> c
[1, 2, 3]
>>> d
[1, 2, 3]

見た目だけなら d のやり方が一番好きだけど、パフォーマンス的にはどれが一番マシなんだろう…?

ちなみに辞書のコピーは 3.4.12 節では copy() メソッドによる方法しか示されていなかったが、少なくとも dict() コンストラクタを使う方法は同様にイケるっぽい。

Python ではリストとタプルは別物である

Perl で慣れてるのでこういう表現になります。

Perl では値をカンマで区切ったものは何でもリストになります。 Python では値をカンマで区切ったものはタプルとなり、要素の追加・削除・変更ができません。

局面に応じて値の並びをミュータブルに扱いたいかイミュータブルに扱いたいかを選べるようになっているのは良いことだと思います。そうなっていることで不便を感じることも多分無いと思います。 Perl のリストの仕組みに不便を感じたことはありませんが。

強いて言えば値 1個だけのタプルの書き方がちょっとキモイですね…。

>>> (1)
1
>>> 1,
(1,)

Perl みたいに丸かっこで括ったらリスト、じゃないやタプルとして扱われる、でも良かった気もしますが…

ただ、C++ や C# などでライブラリに存在するタプルオブジェクトなんかに比べれば、これが本来タプルに求められるべき使い勝手なんだろうな、という気はします…(´・ω・`)。

dict コンストラクタ

2要素のタプルのタプルからでも生成できるみたいだけど、引数にタプルのリテラルを指定する場合はカッコをいっぱい挟まないといけない模様…(´・ω・`)

>>> dict(1, 2, 3, 4, 5, 6)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: dict expected at most 1 arguments, got 6
>>> dict((1, 2), (3, 4), (5, 6))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: dict expected at most 1 arguments, got 3
>>> dict(((1, 2), (3, 4), (5, 6)))
{1: 2, 3: 4, 5: 6}

dict コンストラクタに指定できる引数の数が 1つだけなので、まぁ当然っちゃ当然ですが… 素直に {} 使えってことですね。

dict_keys はそのまま sorted に渡せる

辞書の keys() メソッドは dict_keys オブジェクトを返す。リストとして扱うには list() コンストラクタに渡す必要があるが、ソートしたキーの一覧が必要な場合はそのまま sorted() 関数に渡せばいいっぽい。

>>> da = { 'hoge': 'foo', 'fuga': 'bar', 'piyo': 'baz', 'piyopiyo': 'qux' }
>>> da.keys()
dict_keys(['hoge', 'piyo', 'piyopiyo', 'fuga'])
>>> list(da.keys())
['hoge', 'piyo', 'piyopiyo', 'fuga']
>>> sorted(da.keys())
['fuga', 'hoge', 'piyo', 'piyopiyo']

辞書のキーの集合を得るなら keys() メソッドの呼び出しも不要

これは 3.5.2 節に記載の通り。集合は for ループで回すこともできるので、普通の用途ならそもそもリストにする必要はないってことだやね。

>>> da = {'hoge': 'foo', 'fuga': 'bar', 'piyo': 'baz', 'piyopiyo': 'qux'}
>>> set(da)
{'hoge', 'piyopiyo', 'fuga', 'piyo'}
>>> for a in set(da):
...     print(a)
... 
hoge
piyopiyo
fuga
piyo

本当に for ループで回すだけなら keys() が返す dict_keys でもイケるようですが。

>>> for a in da.keys():
...     print(a)
... 
hoge
piyo
piyopiyo
fuga

集合の使い勝手はむしろ集合同士の比較演算にあるようです。 (3.5.4 節)

辞書はキーにタプルが使える

タプルとそれ以外との混在も可能っぽい。

>>> da = {'foo': 1, 'bar': 2, ('foo', 'bar'): 3, 'baz': 4, ('foo', 'baz'): 5}
>>> da
{'bar': 2, 'baz': 4, ('foo', 'bar'): 3, 'foo': 1, ('foo', 'baz'): 5}
>>> da['foo', 'bar']
3

DBMS でも 2つのカラムが PK になる場合とかありうるので、データ構造が無駄に複雑にならなくて済む場合もあってよさそう。

2017 年 2 月 24 日 by 村山 俊之

タグ:

コメントをどうぞ