Python Неизвестный поиск паттернов - PullRequest
0 голосов
/ 13 июня 2011

Хорошо, в основном я хочу сжать файл, используя код повторно, а затем во время выполнения заменить отсутствующий код.То, что я придумал, действительно ужасно и медленно, по крайней мере, это работает.Проблема в том, что файл не имеет определенной структуры, например, 'aGVsbG8 = \ n', поскольку вы можете видеть его кодировку base64.Моя функция очень медленная, потому что длина файла 1700+, и она проверяет шаблоны на 1 символ за раз.Пожалуйста, помогите мне с новым лучшим кодом или, по крайней мере, помогите мне оптимизировать то, что я получил :).Добро пожаловать!Кстати, я уже пробовал библиотеки сжатия, но они не сжимали так хорошо, как моя уродливая функция.

def c_long(inp, cap=False, b=5):
    import re,string
    if cap is False: cap = len(inp)
    es = re.escape; le=len; ref = re.findall; ran = range; fi = string.find
    c = b;inpc = inp;pattern = inpc[:b]; l=[]
    rep = string.replace; ins = list.insert
    while True:
        if c == le(inpc) and le(inpc) > b+1: c = b; inpc = inpc[1:]; pattern = inpc[:b]
        elif le(inpc) <= b: break
        if c == cap: c = b; inpc = inpc[1:]; pattern = inpc[:b]
        p = ref(es(pattern),inp)
        pattern += inpc[c]
        if le(p) > 1 and le(pattern) >= b+1:
            if l == []: l = [[pattern,le(p)+le(pattern)]]
            elif le(ref(es(inpc[:c+2]),inp))+le(inpc[:c+2]) < le(p)+le(pattern):
                x = [pattern,le(p)+le(inpc[:c+1])]
                for i in ran(le(l)):
                    if x[1] >= l[i][1] and x[0][:-1] not in l[i][0]: ins(l,i,x); break
                    elif x[1] >= l[i][1] and x[0][:-1] in l[i][0]: l[i] = x; break
                inpc = inpc[:fi(inpc,x[0])] + inpc[le(x[0]):]
                pattern = inpc[:b]
                c = b-1
        c += 1
    d = {}; c = 0
    s = ran(le(l))
    for x in l: inp = rep(inp,x[0],'{%d}' % s[c]); d[str(s[c])] = x[0]; c += 1
    return [inp,d]

def decompress(inp,l): return apply(inp.format, [l[str(x)] for x in sorted([int(x) for x in l.keys()])])

Ответы [ 2 ]

2 голосов
/ 13 июня 2011

Самый простой способ сжатия данных в кодировке base64 - это сначала преобразовать их в двоичные данные - это уже сэкономит 25 процентов пространства хранения:

>>> s = "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=\n"
>>> t = s.decode("base64")
>>> len(s)
37
>>> len(t)
26

В большинстве случаев вы можете сжатьСтрока еще дальше, используя некоторый алгоритм сжатия, например t.encode("bz2") или t.encode("zlib").

Несколько замечаний к вашему коду: Есть много факторов, которые делают код трудным для чтения: непоследовательный пробел, слишком длинные строки,бессмысленные имена переменных, недиоматический код и т. д. Пример: ваша функция decompress() может быть эквивалентно записана как

def decompress(compressed_string, substitutions):
    subst_list = [substitutions[k] for k in sorted(substitutions, key=int)]
    return compressed_string.format(*subst_list)

Теперь это уже намного более очевидно, чем она занимается.Вы можете пойти еще дальше: почему substitutions словарь со строковыми ключами "0", "1" и т. Д.?Мало того, что странно использовать строки вместо целых чисел - вам вообще не нужны ключи!Подойдет простой список, и decompress() упростится до

def decompress(compressed_string, substitutions):
    return compressed_string.format(*substitutions)

. Вы можете подумать, что все это вторично, но если вы сделаете остальную часть своего кода одинаково читабельной, вы найдете ошибки в своем кодесам.(Там есть ошибок - он вылетает для "abcdefgabcdefg" и многих других строк.)

1 голос
/ 13 июня 2011

Обычно программу прокачивают по алгоритму сжатия, оптимизированному для текста, а затем запускают его по exec, например

code="""..."""
exec(somelib.decompress(code), globals=???, locals=???)

Возможно, файлы .pyc / .pyo уже сжаты, и можно проверить, создав файл с x="""aaaaaaaa""", затем увеличив длину до x="""aaaaaaaaaaaaaaaaaaaaaaa...aaaa""" и увидев, заметно ли изменяется размер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...