[心得] pattern test的 _? 運算子
學MM這個程式就跟學外語或其他東西是一樣的,學然後知不足......才怪
是"若不足 則去學"才比較精確吧。所以多摸多玩,設定想法並想辦法達成,
過不久就會學會一堆自己想起來都覺得驚訝「哇靠,這個你也懂」的技巧。
當然滿足感只限於自我長進這方面,不懂的卻還是可數無限多。
- - -
Mathematica 的 pattern test 是設計來當萬用工具來的,在說明文件中的
tutorial/EverythingIsAnExpression 就挑明說了: 所有MM裡的東西都是
抽象符號的總合,可以用pattern與函數做出任何manipulation,胡搞瞎搞。
不過因為種類很多,有的pattern規則從來沒用過,直到有一天發現"噢不,為啥
這函數規定只能這樣寫"
然後說明文件裡又語焉不詳只能自己搞半天......真有趣的經驗
這裡要講的是我摸索出來 Cases[] 和 DeleteCases[] 函數中怎麼使用進階條件判斷
來從list裡面挑東西或刪東西
這點原說明裡根本沒有例子很討厭,害我一直以為Cases只能作非常簡單的事情
http://reference.wolfram.com/mathematica/ref/Cases.html
先從平常的 /. rule 講起
一、
{1,2,3,4,5} /. 2 -> p 輸出 {1,p,3,4,5}
:: 2 -> p 是最簡單的rule
二、
{a,b,2,c,5} /. _Integer -> x {a,b,x,c,x}
:: 使用Head(類別)的判斷條件,是將類型放在 _ 後面
三、
{a[1],b[1],a[3],c[4]} /. a[x_] -> x {1,b[1],3,c[4]}
:: 我把這個理解成是辨識一模一樣的架構的pattern
四、
{1,a,3,4,5} /. x_ -> x+1 {2,a+1,4,5,6}
:: 把一個啞變數x放在 _ 之前,表示在l.h.s.命名符合的元素為x,並在 r.h.s.
作x+1並返回這件事
五、
{1,2,3,4,5} /. x_ /; PrimeQ[x] -> p
:: rule加上"進階條件"的方式,是在箭頭之前加上 /; 判斷式 (輸出為True/False)
之任意函數,箭頭後的代換唯有判斷為True才會執行。
但像五這樣的條件判斷用法
在 Cases[list, pattern] 裡不能用= =+
原因據我理解是 /; 不屬於pattern的結構,它是Rule (lhs /; -> rhs )裡的一部分
而整個rule只有 lhs 屬於純pattern,也就是和 _ 記號有關的小朋友們
如何在pattern本身裡面加入條件判斷,最好是能帶自訂函數的那種? 答案是用到
_?test 運算子
即說明文件中的 http://reference.wolfram.com/mathematica/ref/PatternTest.html
很不幸它又沒多說,詳細的使用例竟給我藏在
tutorial/PuttingConstraintsOnPatterns
裡面的第二段
簡單而言 ?和test之間沒有空格
test須是一個 True/False函數
執行中程式會把每件東西都丟給函數,當函數返回True 即 match pattern
如果test是pure function,就是#加&的那種,必須用( )包起來
使用例
Cases[{{a, 3}, 5, {b, 7}, g}, _List?(First[#] == a &)]
輸出: {{a,3}}
這裡整串 _List?(First[#] == a &) 都是純pattern而不是前面的 rule
所以根據這個原理,前面的 {1,2,3,4,5} /. x_ /; PrimeQ[x] -> p
也可以寫作 {1,2,3,4,5} /. x_?PrimeQ -> p 作用相同
- - -
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.213.88
※ 編輯: jurian0101 來自: 140.112.213.88 (04/18 04:54)
※ 編輯: jurian0101 (140.112.125.216), 10/21/2014 13:45:25
Mathematica 近期熱門文章
PTT數位生活區 即時熱門文章