新しいアカウントで始めました。

身の回りの出来事や写真が中心です。

Python3、reduce、map、filter復習してみました!

2024-03-12 08:36:48 | Python

reduceは使うときに、from functools import reduceが必要のようです。1行目。

map、filterは付いてませんが…。

5、6行目でlambdeを変数に代入してますが、配列に代入してみました。出来ないようです。その違いが

分からなかったです?

reduceはListの処理をしますが、結果は1個ですね。出力の1段目と2段目。

 

mapは1個目のパラメータの関数を2個目のパラメータのListに適用します。結果はListと

あったんですがprint(m)で、上手く表示されなかったと思いますが?出力の3段目。

 

filterは14行から17行より20行目のほうが、慣れれば良いかも知れません。

14行目から21行目。

 

感想)関数型プログラミングと言って良いのか?はループ処理を嫌うようです。ループさせるとミュータブルな変数を使う必要があります。

変更させないイミュータブルなオブジェクトを使うことが関数型プログラミングに通じるみたいです。

そんなことが自分が覚えた頃にはなかったと思います。今でもミュターブルとイミュータブルを混乱します?


コメント (2)    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 3.11は13年経っても、忘れら... | トップ | Python3のreduceもう少しやっ... »
最新の画像もっと見る

2 コメント

コメント日が  古い順  |   新しい順
Python3のreduce、map、filter (cametan_42)
2024-03-12 10:23:34
> reduceは使うときに、from functools import reduceが必要のようです。1行目。

そう、Python2.x時代は要らなかったけど、3.xになった時点でreduceはfunctoolsに移動しました。

> 5、6行目でlambdeを変数に代入してますが、配列に代入してみました。出来ないようです。その違いが
>
> 分からなかったです?

リストに代入?出来ますよ。

>>> array = [lambda x, y: x + y, lambda x, y: x * y]
>>> array
[<function <lambda> at 0x7f54b555b370>, <function <lambda> at 0x7f54b54eab00>]

あるいは、タプルで、例えば

>>> t = lambda x, y: x + y, lambda x, y: x * y
>>> t
(<function <lambda> at 0x7f54affeab90>, <function <lambda> at 0x7f54affeaf80>)

ってのもアリです。

> reduceはListの処理をしますが、結果は1個ですね。出力の1段目と2段目。

「畳み込み」なんで。

> mapは1個目のパラメータの関数を2個目のパラメータのListに適用します。結果はListと

> あったんですがprint(m)で、上手く表示されなかったと思いますが?出力の3段目。

Python3.xだとmapはイテレータなんでイテラブルオブジェクトを返します。
従って、printしようとしても中身は見れません。

>>> lst = list(range(1, 11))
>>> m = map(lambda x: x + 1, lst)
>>> print(m)
<map object at 0x7f54affe10f0>


> filterは14行から17行より20行目のほうが、慣れれば良いかも知れません。

filterもmapと同様に、Python3.xではイテラブルオブジェクトを返すイテレータになってます。
従って、両者とも遅延評価的に扱わないのであれば、リスト内包表記を使うのが正解ですね。

ちなみにここは惜しい。

def chk(num):
 return True if num % 2 == 0 else False

これはこう書くべきです。

def chk(num):
 return num % 2 == 0

そもそも、等価判定(==)自体が真偽値を返すんで、True/Falseを返す機構を含んでる。
ここはisamさんだけ、じゃなくって意外と気づいてない人が多いんです。
「真偽判定」はそのままreturnしちゃえ、って事ですね。

>>> f2 = [x for x in lst if chk(x)]
>>> f2
[2, 4, 6, 8, 10]

> 関数型プログラミングと言って良いのか?はループ処理を嫌うようです。ループさせるとミュータブルな変数を使う必要があります。

その通りです。反復処理は通常、破壊的変更をする為行うんで、関数型プログラミングはその辺を避けます。
もう一つは複文を避ける、と。基本、反復処理だと

for なんとやら:
 あれをして
 これをして
 それをして
 ...

と「複数の処理をする」。一方、基本的に関数型プログラミングではこういう「複文を使う処理」をしない。単一の式で事足りるように持っていくんで、反復処理が要らないんです。

> 変更させないイミュータブルなオブジェクトを使うことが関数型プログラミングに通じるみたいです。

とは言っても、Pythonでのイミュータブルなオブジェクトってタプルくらいしかないですけどねぇ。

> そんなことが自分が覚えた頃にはなかったと思います。今でもミュターブルとイミュータブルを混乱します?

これも、昔はPCのリソースが小さかったから、です。
イミュータブルオブジェクトの方が「プログラミング上安全だ」ってのはミニコン辺りでは知られてたんだけど、結局、パソコンだとイミュータブルオブジェクトを使うと小さいメモリが余計圧縮される。そして、ガベージコレクタが走り回るんで、CPUへの負荷も高かったんですね。昔のPCは貧弱だったから(笑)。
もちろん、コンパイラがあれば、理論的には「非破壊的に書いた」関数型プログラミングのコードを、マシン語レベルだと「破壊的操作して」効率を上げる事が出来るんですが、そもそも「コンパイラの効率化」ってのも色々研究進んだのは比較的近年なんですよね(笑)。
何度かコッチのブログでは書いてるけど、ファミコン/スーファミ時代だとそのテのゲーム機用のプログラミングをする際、当時のプログラマがアセンブリでプログラムをして、高級言語を信じなかったのはその辺が背景です。当時のコンパイラは非効率的なマシンコードを吐いてたんです(笑)。
だからその時代と比べるとコンパイラの「最適化」技術がどんどん良くなってきた、と。
それでisamさんが「昔はそんなん無かったのに・・・」となるわけです(笑)。
返信する
コメント有難う御座います。 (isam)
2024-03-12 20:01:30
 変数に代入できる、代入で良いんでしたか?、ものはリストでも代入できるようです。
返信する

Python」カテゴリの最新記事