ゆずめも

私による私のためのメモ的なブログです。主に勉強した事について書いてます。

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の記事書く

とりあえずリスト内包表記楽しい

過去触った言語だとなかったので楽しくて使ってるけど
チームでやってるので、すっと理解できないようなのだと使わない方がいいかなって思った