DRYな備忘録

Don't Repeat Yourself.

Pythonでdictionaryの各要素に処理を加えた別のdictionaryをつくる

TL;DR

>>> { k:list(map(lambda s: int(s)**2, v.split('-'))) for (k,v) in src.items()}
{'foo': [1, 4, 9], 'bar': [16, 25, 36]}

f:id:otiai10:20190412125100p:plain

やりたいこと

入力

{
  'foo': '1-2-3',
  'bar': '4-5-6',
}

出力

{
  'foo': [1, 4, 9],
  'bar': [16, 25, 36],
}

みたいなこと。

解決

src = {'foo': '1-2-3', 'bar': '4-5-6'}

dest = {
    k: list(map(
            lambda s: int(s)**2,
            v.split('-'),
    )) for (k, v) in src.items()
}

# {'foo': [1, 4, 9], 'bar': [16, 25, 36]}

知見

  1. dictは、itemsメソッドで、(key, value)のタプルのリストが得られる
    1. 正確には得られるのはdict_itemsであり、appendなどは無いが、リストとして扱う上では困らない
  2. タプルのリストはforでそれぞれ多値を拾うことができる
    1. for (name, age) in [('otiai10', 100), ('otiai20', 200)] のように
  3. map関数でリストのそれぞれの要素に対して処理をapplyできる
    1. ただし、この返り値はmap objectであり、listではないので、list()でリストにしてやる必要がある
  4. 文字列分割はstr.split(delim)
  5. 無名関数をlambdaで作ることができる
    1. ただし、複数行のlambdaをつくることはできない?っぽいので、見通しも悪くなるので関数は別定義したほうがよい
  6. dictの初期化において、keyにも変数を使える
    1. 下記参照
>>> key = 'name'
>>> val = 'otiai10'
>>> {key:val}
{'name': 'otiai10'}

WETな備忘録として