Last active
August 29, 2015 14:05
-
-
Save kwatch/f3f81c7194ca82c168f6 to your computer and use it in GitHub Desktop.
問題5:入れ子になっているリストを、インデント幅2の文字列に変換する関数 indented(arr, width=2) を定義してください。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # -*- coding: utf-8 -*- | |
| ## | |
| ## 問題5:入れ子になっているリストを、インデント幅2の文字列に変換する関数 indented(arr, width=2) を定義してください。 | |
| ## 例: | |
| ## nested = [1, [2, [3, 4], 5, [6]]] | |
| ## string = indented(nested) | |
| ## print(string) | |
| ## #=> 1 | |
| ## # 2 | |
| ## # 3 | |
| ## # 4 | |
| ## # 5 | |
| ## # 6 | |
| ## | |
| def indented(nested, width=2): | |
| space = " " * width # 初期値を設定 | |
| buf = [] | |
| _indented(nested, 0, buf, space) # メイン処理を実行 | |
| return "".join(buf) # 戻り値を構築 | |
| def _indented(nested, depth, buf, space): # メイン処理を担当する関数 | |
| indent = space * depth | |
| for x in nested: | |
| if isinstance(x, list): | |
| _indented(x, depth+1, buf, space) # 再帰呼び出し | |
| else: | |
| buf.append("%s%s\n" % (indent, x)) | |
| ## または | |
| def indented2(nested, width=2): | |
| space = " " * width # 関数内関数で使う値を設定 (注1) | |
| buf = [] | |
| # | |
| def fn(nested, depth): # メイン処理を担当する関数内関数 | |
| indent = space * depth | |
| for x in nested: | |
| if isinstance(x, list): | |
| fn(x, depth+1) # 再帰呼び出し時の引数が減っている! | |
| else: | |
| buf.append("%s%s\n" % (indent, x)) | |
| # | |
| fn(nested, 0) # メイン処理を実行 | |
| return "".join(buf) # 戻り値を構築 | |
| ## (注1) 関数内関数から、外側のローカル変数にアクセスするのは、 | |
| ## 通常のローカル変数やグローバル変数へのアクセスと比べ、かなり遅い。 | |
| ## そのため、indented2() は indentend() と比べて動作が遅くなる。 | |
| ## 回避策としては、次のように引数のデフォルト値として設定することである。 | |
| ## def fn(nested, depth, buf=buf, space=space): | |
| ## こうすると、fn() から外側のローカル変数へのアクセスがなくなるため、 | |
| ## indented() が高速になる。 | |
| if __name__ == '__main__': | |
| nested = [1, [2, [3, 4], 5, [6]]] | |
| expected = ( | |
| "1\n" | |
| " 2\n" | |
| " 3\n" | |
| " 4\n" | |
| " 5\n" | |
| " 6\n" | |
| ) | |
| #print(indented(nested)) | |
| assert indented(nested) == expected | |
| assert indented2(nested) == expected |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment