私の質問は、コードのどの部分/行が 2 番目のバージョンでコストがかかるのか、そしてその理由は? どちらも同じように機能し、同じ結果をリスト形式で返します。
いいえ、そうではありません。疑わしい場合は、常にプロファイルを作成してください。各操作のコストの全体像が示されます。以下の O/P を見るだけで、2 番目の関数で何がコストがかかるかがわかりますか?
>>> cProfile.run("replace1_word2('foo bar baz')")
313 function calls in 0.000 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <pyshell#216>:1(replace1_word2)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
12 0.000 0.000 0.000 0.000 {len}
286 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
12 0.000 0.000 0.000 0.000 {range}
>>> cProfile.run("replace1_word('foo bar baz')")
27 function calls in 0.000 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <pyshell#220>:1(replace1_word)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
12 0.000 0.000 0.000 0.000 {len}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
12 0.000 0.000 0.000 0.000 {range}
append を置き換えるもの (またはバージョン 1 がどのようにリストを生成するか) を説明するように注意してください
Python では、関数呼び出しに余分なオーバーヘッドがあります。前者の場合、list.append
は複数回呼び出されますが、リスト内包表記の場合と同様に、リストは単一の式として生成されます。したがって、ある意味では、ループ構造を持つリスト内包表記には同等の表記法はありません。リスト内包表記は、ループの装飾された構文ではなく、Python の強力なツールです。
エピローグ
この問題を解決する関数を書くように言われたら、私は次のようになります
>>> from itertools import product
>>> from string import ascii_lowercase
>>> def replace1_word4(word):
words = ('{}'.join([word[:w], word[w+1:]]) for w in range(len(word)))
return [word.format(replace)
for word, replace in product(words, ascii_lowercase)]