Nur um Ihnen eine Vorstellung davon zu geben, warum es eine wirklich schlechte Idee ist, Ihre LZW-Kompressor-Schleife in ein Listenverständnis zu stopfen, habe ich tatsächlich weitergemacht und etwas verrückten Code geschrieben, der genau das tut.
Es verwendet einige ziemlich zwielichtige Tricks, und es wird nicht auf Python 3 arbeiten, weil in Python 3 ein Listenverständnis in seinem eigenen Geltungsbereich läuft; In Python 2 läuft ein Listenverständnis im Umfang des umgebenden Codes. Und das bedeutet, dass mein Trick, den ursprünglichen Puffer in die List-Comp zu übergeben, in Python 3 nicht funktioniert.
Erstens, hier ist Ihr ursprünglicher Code in eine Funktion eingewickelt, mit ein paar Variablennamenänderungen und ein paar hinzugefügt Extras, um es zu einem lauffähigen, testbaren Beispiel zu machen.
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))
Ausgang
[116, 104, 105, 115, 32, 100, 97, 116, 97, 32, 130, 32, 128, 138, 133]
22 -> 15
Wir eigentlich nicht brauchen, um das Codebuch der Größe in einer separaten Variable zu halten. Wie bei allen integrierten Python-Containertypen überwacht ein Diktat seine Größe, und wir können die Funktion len()
verwenden, um sie zu erhalten. So können wir diese zwei Zeilen ersetzen:
codebook[newbuff] = dict_size
dict_size += 1
mit dieser Zeile:
codebook[newbuff] = len(codebook)
Jetzt ist hier die verrückte Version, die eine Liste Verständnis verwendet. Denken Sie daran, Kinder, bittenicht versuchen Sie dies zu Hause! :)
Beachten Sie, dass diese Version nicht nur schwieriger zu lesen ist als die erste, die ich gepostet habe, sie ist auch weniger effizient.Und wie ich zu Beginn sagte, ist es weniger portabel, und es verwendet einige total zwielichtige Tricks, die niemals in ernstem Code verwendet werden sollten.
Listenübersichten sind cool, und wenn Sie einmal daran gewöhnt sind, können sie Ihren Code prägnanter machen, was die Lesbarkeit verbessern kann, solange Sie nicht zu viel in ihnen machen. Eine Liste comp leicht effiziente als entsprechender Code .append
in einer „traditionellen“ Stil for
-Schleife, aber sie sind keine Zauberei, und mit einem unverständlichen Liste Verständnis statt über eine schöne klar lesbar traditionelle for
Schleife ist nicht Pythonic .
Warum muss dieses in ein Listenverständnis konvertiert werden? Das würde die Lesbarkeit wirklich verletzen. –
Warum möchten Sie? Wenn es nach einem teuflischen Voodoo möglich wäre, all das in ein Listenverständnis zu stecken, wäre es völlig unlesbar. –
'[do_everything_youre_doing_in_the_loop (Zeichen) für Zeichen in String]' ...? Dies ist zu viel Code, um in ein Verständnis zu inline ... – deceze