先ずは、試行錯誤の経過を。
A:付いた出力は、二重ループのリストのアペンドなので、まあ、理解は出来ます。インデックスを使用という課題は残ります。
B:の付いた出力は、リストは1個だけで、それをどれだけ使い、リストにするか?A:とは意味が少し違いますが、やはりインデックス使用でしょう。
C:の付いた出力もリストを作るまでは、様式は違いますが、同じでしょう。reduce、lambdaが付け加わって、数字から文字に変わりました。これも対象は1個のリストでしょう。
D:の付いた出力は、一般的な例に良く出てます。いちばん簡単なreduceの使い方でしょう。でも意外と深い意味がありそうです。見た目以上に。
E:の付いた出力は、リストのリストで試したものです。結果はリストです。内容も良いのです。
F:は今までやってきたことから、リストの中の合計を出してます。
G:はリストの部分をCametanさんから教えてもらったものに一部置き換えてみました。
H、Iは試行錯誤でやってみたのですが、reduceが二重になってます。Cametanさんから教えてもらったコードはreduceが1個ですので、どう書けば1個に出来るんでしょうか?
[print(k, end='') for k in ['C:'+ ', '.join([str(j) for j in i]) + '\n' for i in reduce(lambda y, x: [[x]] if y == [] else [*y, y[-1] + [x]], lst, [])]]
I:
print(f'I:{sum(reduce(lambda y, x: y + [y[-1] + x], [1, 2, 3, 4, 5], [0]))}')
もともと回転が遅い方ですので。(笑)
reduceは慣れるには訓練と時間が必要です。
もう一つ言うと、「最初に学んだプログラミング言語」の影響って残るんですよ。一番影響が大きくなる。
多分、isamさんの場合だとVisual Basic?
その影響や考え方、コーディングスタイルが強烈なんでreduceなんかの関数型言語の考え方に「切り替える」のが難しい。
例えばなんか思いついた時に「頑張って」F#を使って書いてみる、とか相当意識的にしないと、「処女を捧げたプログラミング言語」の影響下から抜けるのは大変なんです。
VBの兄弟言語?といえるか、VBAもある程度はやってますので、抜け出せないのが半端ない、のかも知れませんね。
なるほど。
だとしたら、「抽象度が高い」プログラミング言語は、その「配列」を如何にして簡単に扱うか、を念頭に置いた言語だ、って捉えていいでしょう。
要は「配列要素を一つ一つ」バラバラにして扱わない。「まとめて」扱う。reduceもその一つ、です。
「配列要素を一つ一つ」取り出さずに、「まとめて扱う」辺りで思考の飛躍が必要なんです。
> VBの兄弟言語?といえるか、VBAもある程度はやってますので、抜け出せないのが半端ない、のかも知れませんね。
あー、なるほど・・・VBA・・・・・・。
いや、一般人的な意味で言うと、プログラミングが「一番役立つ」局面って、どうしてもMicrosoft WordやExcel対象に色々やる、って事になるんで・・・もうちょっと複雑でもAccess対象か。
確かに必然的にその辺が入口になるのは、一般的には避けられないですよねぇ。
ちなみに、Visual BasicもVBAも、何度か言ってるけど、「本物の」BASICではない。いや、本物じゃないからダメな言語って意味じゃなくって、言っちゃえば多分「本物の」BASICより良くなってる(笑)。本物のBASICなんて既に殆ど誰も使ってない好事家のプログラミング言語になってますし。
公式にはISO/JIS辺りで1990年に制定されたFullBASICってのが「本物の」BASICなんだけど、処理系も無いし、こっちの方はほぼ絶滅してて(笑)、言い換えると、Microsoftが殆ど唯一のBASIC「方言」のベンダーになって久しい。
日本だと十進BASICが有名なJIS FullBASICの処理系ですが・・・。
十進BASIC:
http://hp.vector.co.jp/authors/VA008683/
ハッキリ言って、Pythonが出た時点で、FullBASICはPythonよか難しい言語になっちゃった。「BASICが簡単だった時代」は1980年代で終わってますね。あとはVBとVBAが頑張ってる、ってのがBASIC周りかなぁ・・・・・・。
いずれにせよ、この文書も何度か紹介してますが。
バベル案内:
http://www.aoky.net/articles/steve_yegge/tour_de_babel.htm
スティーヴ・イエギってハッカーが書いてた通りだとは思います。
「満足を育むのは、多くの場合コンピュータ言語自体ではなく、馴染んでいるということによってだ。慣れ親しんだもので満足してしまう前に、もっといい言語のエキスパートになる必要がある。」
プログラミング言語攻略の目標をどの辺に設定するか、ってのは個人の好みですが、いずれにせよ、ある程度マジメに考えるなら、「なんか思いついたネタ」を書く場合、意識的に、OCaml/F#で書くようにする、とかisamさんのリストで言うとScalaとか?その辺を「手に馴染む」まで使ってみる、とかがいいんじゃないのかなぁ。
いや、Lispでもいいんだけど、Lispだとそれこそ好き嫌いが分かれるんで(笑)。やっぱ括弧と前置記法の問題が、ね。その点OCaml/F#やScalaはまだ「フツーのプログラミング言語の範疇」の見た目なんで(笑)。
もちろんPythonでもいいんだけど、意外とPythonで「関数型プログラミングを意識して」記述するのもなかなか大変なんで、ちとPythonを「見下ろす」視点も必要かな、と。
Cametanさん、が書いていたレベルのコードも見当たりませんでした。多分難しいので、書かないのでしょう。
rubyはもしかしたら有るかも知れませんが使っている言葉は、違いますので探せませんでした。
Scalaでも同様です。結論としては、一般的な言語だと、関数型のプログラミングは目指せますが、手続き型、命令形でも、オブジェクト指向でもやれます。みたいなんで、書く方の意識の問題とも、言えるんですかね?
一時フィボナッチ数列が書ければ、免許皆伝と有ったように思いますが、どこで見たか思い出せません。
その時lambdaのx,y: y,xの記述も有ったように思いますが?
Rubyにもreduceメソッドはあるけど、基本的な名称はinjectになってるのかな?
instance method Enumerable#inject:
https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/inject.html
> Scalaでも同様です。
Scalaにもあるみたいですよ。まぁ、関数型言語ベースなら当然と言えば当然ですが。
Scala の Seq に定義されているメソッドを試す (7) ~畳み込み~:
https://waman.hatenablog.com/entry/2017/03/19/022907
> 一般的な言語だと、関数型のプログラミングは目指せますが、手続き型、命令形でも、オブジェクト指向でもやれます。みたいなんで、書く方の意識の問題とも、言えるんですかね?
そう、書く方の意識の問題です。
言い換えると、Lisp以外だと「高階関数」と言うモノの使い方、とかそういうノウハウが実は意外と知られていない。強力な機能の「使い方」とか「使いどころ」が分かってない人の方が多いだけ、です。
と言う事は、Lisperの方々「だけ」が良く知ってる、って事になりかねませんが(笑)。
基本的に、この辺の事柄にLisper以外で精通してる人って、Haskellユーザーくらいしかいないかも・・・反復は原則、「破壊的変更」前提なんだけど、そもそもHaskellはその「破壊的変更」を全く許さない「純粋関数型言語」なんで、ユーザーは高階関数とか「使いこなさないと」どうにもならん、って縛りがあるから、ですね。
ただ、いっつも言ってるけど、結局、破壊的変更しない方が結果色々とラクではあるんです。
> 一時フィボナッチ数列が書ければ、免許皆伝と有ったように思いますが、どこで見たか思い出せません。
> その時lambdaのx,y: y,xの記述も有ったように思いますが?
ああこれ?
ローマ数字を整数値に変換する:
https://blog.goo.ne.jp/cametan_42/e/6454a7fd9770ca9005975e2de8c31626
そうです。自力でreduce使ってフィボナッチ数列が書ければテクニック的には殆ど学んだ、って言っていいと思う。
是非ともトライしてみてください。