なぜ実際にのLZWコンプレッサーのループをリストの理解に詰め込んでもらうのが悪い考えを伝えるために、私は実際に先に進み、ちょうどそれを行う狂ったコードを書いています。
Python 3ではリスト内包が独自のスコープで実行されるため、かなり面倒なトリックが使用され、Python 3では機能しません。 Python 2では、リスト内包は周囲のコードの範囲で実行されます。これは、元のバッファをリストcompに渡すという私のやり方がPython 3ではうまくいかないことを意味します。
まず、元のコードを関数にラップし、いくつかの変数名を変更します。それを実行可能でテスト可能な例にするためのエキストラ。
from __future__ import print_function
def lzw_compress_Boa(data):
dict_size = 128
codebook = {chr(i): i for i in range(dict_size)}
output_list = []
oldbuff = ""
for ch in data:
newbuff = oldbuff + ch
if newbuff in codebook:
oldbuff = newbuff
else:
output_list.append(codebook[oldbuff])
codebook[newbuff] = dict_size
dict_size += 1
oldbuff = ch
return output_list
data = 'this data is this data'
output_list = lzw_compress_Boa(data)
print(output_list)
print(len(data), '->', len(output_list))
出力
[116, 104, 105, 115, 32, 100, 97, 116, 97, 32, 130, 32, 128, 138, 133]
22 -> 15
私たちが実際に別の変数に、コードブックのサイズを維持する必要はありません。 Pythonに組み込まれているすべてのコンテナ型と同様に、dictはそのサイズを追跡しており、len()
関数を使用してそれを取得できます。このラインで
codebook[newbuff] = dict_size
dict_size += 1
:だから私たちは、これらの2行を置き換えることができ
codebook[newbuff] = len(codebook)
は今ここにリストの内包を使用してクレイジーバージョンです。子供を覚えて、してください家でこれを試してみてください! :)
このバージョンは、私が投稿した最初のものより読むのが難しいだけでなく、効率も悪いことに注意してください。私が最初に言ったように、移植性が低く、深刻なコードでは決して使用しないでください。
リスト内包はすばらしく、使い慣れたらコードを簡潔にすることができます。コードをあまり使わない限り、読みやすくすることができます。リストCOMPは「伝統的」なスタイルで.append
for
ループを使用して同等のコードよりも少しより効率的ですが、彼らは魔法ではありません、代わりにAA素敵な明確な読みやすい伝統的なfor
ループの不可解なリストの内包表記を使用すると、ない Python的です。
なぜこれをリストの理解に変換する必要がありますか?それは本当に読みやすさを傷つけるでしょう。 –
なぜあなたはしたいですか?何らかの悪魔的なブードーによって、すべてのことをリスト内包にすることができれば、それは全く読めないでしょう。 –
'[do_everything_youre_doing_in_the_loop(文字列)の文字列]' ...?これは理解するためにあまりにも多くのコードです... – deceze