Skip to content

Instantly share code, notes, and snippets.

@kwatch
Last active August 29, 2015 14:05
Show Gist options
  • Save kwatch/f3f81c7194ca82c168f6 to your computer and use it in GitHub Desktop.
Save kwatch/f3f81c7194ca82c168f6 to your computer and use it in GitHub Desktop.
問題5:入れ子になっているリストを、インデント幅2の文字列に変換する関数 indented(arr, width=2) を定義してください。
# -*- 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