|
2.2.4 リストや式への関数の部分的適用
リストの取扱いにおいて,リストの要素ひとつひとつに関数を作用させなければならないときがある.そのようなときは,Mapを使う.
入力したリストの各要素にfを適用する.
In[1]:= Map[f, {a, b, c}]
Out[1]= 
入力したリストの最初の2要素を抽出する関数を定義する.
In[2]:= take2[list_] := Take[list, 2]
Mapを作用させ,take2をリストの各要素に適用させる.
In[3]:= Map[take2, {{1, 3, 4}, {5, 6, 7}, {2, 1, 6, 6}}]
Out[3]= 

リスト要素への関数の適用
Map[f, expr]を使うと,関数fを式exprの各要素に個別に適用することができる.適用の対象になる式exprはリストだけでなくどんな式でもよい.
加法式の各要素にfを適用させる.
In[4]:= Map[f, a + b + c]
Out[4]= 
こうすると,gの各引数に Sqrtを適用させることができる.
In[5]:= Map[Sqrt, g[x^2, x^3]]
Out[5]= 
Map[f, expr]は,関数を式の第1レベルにある部分に適用させるためにある.式の全レベルの全部分に関数を適用させるには MapAll[f, expr]を使う.
行列 mを定義しておく.
In[6]:= m = {{a, b}, {c, d}}
Out[6]= 
Mapを使い,mの第1レベルにfを適用させる.この場合,第1レベルは行列の列に相当する.
In[7]:= Map[f, m]
Out[7]= 
MapAllを使うと,fは mの全レベルに適用される.出力された式を見ると,関数fがすべての部分に適用されているのが分かる.
In[8]:= MapAll[f, m]
Out[8]= 
Mapの使用において,2.1.7で説明してあるレベルの指定法を使うことで,式の任意部分に関数を適用させることもできる.
レベル2のmの部分だけに fを適用させる.
In[9]:= Map[f, m, {2}]
Out[9]= 
Heads->Trueの設定をしておくと,要素だけでなく各部分の頭部にもfを適用させることができる.
In[10]:= Map[f, m, Heads->True]
Out[10]= 

式の違った部分に関数を適用させるためのいくつかの方法
Mapにレベル指定をしておくことで,適用させたい関数を式のどのレベルにでも適用させることが可能である.また,MapAtを使えば,関数を適用させたい式の部分を位置で指定することもできる.位置は,2.1.4で説明してある添数の指定法に従い指定する.
行列を入力する.
In[11]:= mm = {{a, b, c}, {b, c, d}}
Out[11]= 
部分 {1, 2}と部分 {2, 3}にfを適用させる.
In[12]:= MapAt[f, mm, {{1, 2}, {2, 3}}]
Out[12]= 
mmの中でbが現れる位置のリストを作る.
In[13]:= Position[mm, b]
Out[13]= 
Positionにより作成された位置リストを直接 MapAtに与えることもできる.
In[14]:= MapAt[f, mm, %]
Out[14]= 
まぎらわしさを避けるため,位置はリスト形式で指定する必要がある.指定する添数が1つしかない場合もである.
In[15]:= MapAt[f, {a, b, c, d}, {{2}, {3}}]
Out[15]= 

式の任意部分への関数の適用
式を入力する.
In[16]:= t = 1 + (3 + x)^2 / x
Out[16]= 
完全形で tの内容を確認する.
In[17]:= FullForm[ t ]
Out[17]//FullForm= 
MapAtはどんな式にも使えるが,部分は完全形の並び順に基づいて指定されることに注意.
In[18]:= MapAt[f, t, {{2, 1, 1}, {2, 2}}]
Out[18]= 

式の部分と添数への関数の適用
入力リストの各要素に fを適用させる.結果は,要素の添数を fの第2引数とした形で得ることができる.
In[19]:= MapIndexed[f, {a, b, c}]
Out[19]= 
行列のレベル1,2の両方に fを適用させる.
In[20]:= MapIndexed[f, {{a, b}, {c, d}}, 2]
Out[20]= 
Mapを使うことで,単引数の関数をある式の任意部分に適用することができる.しかし,関数が複数の引数を必要とし,それを複数の式に並列的に適用したい場合には使えない.そのようなときは, MapThreadを代りに使う.

複数式への関数の同時適用
リストにおける同じ位置の要素でペアを組み,ペアごとに fを適用する.
In[21]:= MapThread[f, {{a, b, c}, {ap, bp, cp}}]
Out[21]= 
MapThreadが正確に動作するには, fの適用対象となる式はいくつあっても構わないが,それらは同じ構造であることが必要である.
In[22]:= MapThread[f, {{a, b}, {ap, bp}, {app, bpp}}]
Out[22]= 
Map等の関数を使うことで,部分的に変更した式を生成することができる.場合によっては,新しい式を構築しないで,単に特定の関数を式の部分に作用させる,ということだけを行いたい.例えば,適用させる関数が割当て操作や出力の生成等の副作用をもたらす場合はこれに当たる.

複数式の部分への関数の順次適用と評価
Mapは,入力リストの各要素に fを適用させた新たなリストを構築する.
In[23]:= Map[f, {a, b, c}]
Out[23]= 
Scanは,関数を各要素に適用することで得られた結果を評価はするが,新たな式は生成しない.
In[24]:= Scan[Print, {a, b, c}]



Scan操作は,深さ優先探索で(木表示の葉の部分)から始まる.
In[25]:= Scan[Print, 1 + x^2, Infinity]




|