python3のリスト操作
最近Raspberrypiで電子工作をしていてpython3を使っています
そこでデータ(配列)に対しての処理の仕方がわからなくて調べた
話すこと
とりあえずこれだけあればある程度は戦えるかな…
- map
- filter
- reduce
すべての処理ではテストデータとして、以下の配列を使用します
items = [1, 2, 3, 4]
Map
すべての要素に同じ処理というか、同じ関数を実行します
map関数を使用する場合わかりやすく配列っぽく書いてますが、返り値は配列ではなくイテレータ
関数を定義する
# 2倍する関数 def square(v): return v * 2 map(square, items) # => [2, 4, 6, 8]
リスト内包表記(List Comprehension)
python使ってるなら使いたくなるリスト内包表記*1
計測してないから知らないけど、早いらしい
[x*2 for x in items] # => [2, 4, 6, 8]
たとえば
items = ["aaa", "bb", "cccc"]
みたいな配列があったとして
この文字配列それぞれの文字数が欲しい時とか
items = ["aaa", "bb", "cccc"] [len(x) for x in items] # => [3, 2, 4]
ってできたりする
filter
True
or False
を返すことでリストの要素に絞込をかける
items
から偶数の値だけを取り出す
関数を定義する
def myfilter(v): return v % 2 == 0 filter(myfilter, items) # => [2, 4]
リスト内包表記(List Comprehension)
さっきのmapと比べるとちょっと違う書き方する
[x for x in items if x % 2 == 0] # => [2, 4]
Rubyの後置ifみたい
reduce
配列の要素をまとめて1つの結果を返すのがreduce
こいつだけ若干ややこしくて、python3だとグローバル関数で定義されてないみたいで
functools
とかいう名前空間に入ってるのでimportしてやらないといけない
関数を定義する
from functools import reduce def myreduce(a, b): return a + b reduce(myreduce, items) # => 10
mapしてfilterかけてみる
せっかく覚えたし、リスト内包表記でmapしてfilterしてみよう
[x*2 for x in items if x > 5] # => []
適当に混ぜたらいけるかなと思ったら見事に大失敗したw
mapしてfilterして欲しいんだけど、どうもfilterしてmapしてるっぽくて
[1, 2, 3, 4] => フィルター => [] => マップ
ってなってるみたい(そりゃ無理だ)
試しにifの所をちょっと変えてやると確認できる
[x*2 for x in items if x > 2] # => [6, 8]
一応こうすると動いた
[x*2 for x in items if x*2 > 5] # => [6, 8]
(でもこれmapしてfilterしてる訳じゃないよな…)
〜〜追記〜〜
なんか思いつきでやってみたらできた
[y for y in [x*2 for x in items] if y > 5] # => [6, 8]
まとめ
javascriptやってから新しい言語始めるときは、配列操作から調べるようになった(なんでやろ)
今回の関数定義するパターンは簡単な処理ならlambda
使って定義する方がすっきりしそうだなーと思ったので
気が向いたらlambdaの記事書く
とりあえずリスト内包表記楽しい
過去触った言語だとなかったので楽しくて使ってるけど
チームでやってるので、すっと理解できないようなのだと使わない方がいいかなって思った