リストや辞書の使い方 (揚げ足取り風)

bonlifeです。以下の日記でのPythonでのリスト操作がちょっぴり気になったので揚げ足取ってみました。(bonlife自体がPython素人のくせに…。)

iteritemsやlist代入の綺麗な書き方

リストのコピー

forループで1つずつ取り出して代入
In [1]: l = ['kapi', 'python', 'chu']

In [2]: _l = []

In [3]: for i in l:
   ...:     _l.append(i)
   ...:
   ...:

In [4]: _l
Out[4]: ['kapi', 'python', 'chu']
リスト内包表記
In [5]: _l = [i for i in l]

In [6]: _l
Out[6]: ['kapi', 'python', 'chu']
bonlifeならこうする
In [7]: L = l[:]

In [8]: L
Out[8]: ['kapi', 'python', 'chu']

元のリストのスライシングですよ。はじまりもおわりも指定せずに。(ってちょっと文学っぽい表現。)
「それだったら、もっと簡単にそのまま代入したら!」とかやるとアウチな件。

アウチな例
In [9]: L2 = l

In [10]: L2
Out[10]: ['kapi', 'python', 'chu']

In [11]: L2[0] = 'bonlife'

In [12]: L2
Out[12]: ['bonlife', 'python', 'chu']

In [13]: l
Out[13]: ['bonlife', 'python', 'chu']

In [14]: L
Out[14]: ['kapi', 'python', 'chu']

はい。リストの参照を代入しちゃってる的な何かですよ。元のリストが置き換わってしまう罠。(罠でも何でもないですね、えぇえぇ。) あと、細かい点ですが、小文字のエルはちょっとアレなので使わないのが吉。

補足

リストの要素に対して何らかの処理をしたい場合はリスト内包表記が超便利。

In [15]: L3 = [ i.upper() for i in l]

In [16]: L3
Out[16]: ['BONLIFE', 'PYTHON', 'CHU']
補足2 (copyモジュールを使ってみる)

コピーが目的ならcopyモジュール。

In [1]: import copy

In [2]: l = ['kapi', 'python', 'chu']

In [3]: L2 = copy.copy(l)

In [4]: L2
Out[4]: ['kapi', 'python', 'chu']

中身がややこしかったらcopyモジュールのdeepcopyを使ったり。

辞書をリストに分解

リスト内包表記で辞書を辞書のリストに変換
In [1]: d = {'kapi':1,'python':2,'chu':3}

In [2]: for k,v in d.iteritems():
   ...:     print k,v
   ...:
   ...:
python 2
kapi 1
chu 3

In [3]: L = [{k:v} for k,v in d.iteritems()]

In [4]: L
Out[4]: [{'python': 2}, {'kapi': 1}, {'chu': 3}]

十分に美しい。でも、こういう操作って必要になりますかね。なんとなく、扱いづらいデータ構造になっちゃってる気がしないでもないんですが、いかがでしょう。どういう時にこういうデータ構造にするのか、ちょっと聞いてみたいですね。(あくまでもサンプルってことかしら。)