2012-10-29 2 views

답변

7

run-length encoding을 찾고 있습니다. 여기에 this one에 기반한 Python 구현이 있습니다. 귀하의 예를 들어

import itertools 

def runlength_enc(s): 
    '''Return a run-length encoded version of the string''' 
    enc = ((x, sum(1 for _ in gp)) for x, gp in itertools.groupby(s)) 
    removed_1s = [((c, n) if n > 1 else c) for c, n in enc] 
    joined = [["".join(g)] if n == 1 else list(g) 
        for n, g in itertools.groupby(removed_1s, key=len)] 
    return list(itertools.chain(*joined)) 

def runlength_decode(enc): 
    return "".join((c[0] * c[1] if len(c) == 2 else c) for c in enc) 

:

print runlength_enc("1254,,,,,,,,,,,,,,,,982") 
# ['1254', (',', 16), '982'] 
print runlength_decode(runlength_enc("1254,,,,,,,,,,,,,,,,982")) 
# 1254,,,,,,,,,,,,,,,,982 

(당신의 문자열에 매우 긴 실행이있는 경우에만이 효율적 않습니다).

+1

를 사용하여 내가 보통의-homogonous 목록을 옹호하지 만,'가진 ('1', 1)'약간의 중복 때를 보인다 당신은 단지 '1'을 가질 수 있습니다. 난 당신이 꽤 쉽게 '['1254 ', (', ', 16),'982 ']'를 반환하도록 수정할 수있을 것 같아요. 메모리 사용량 및 디스크 사용량면에서 1 목록, 8 튜플, 8 문자열, 8 정수가있는 버전 대신 훨씬 효율적입니다 (1 목록, 1 튜플, 4 문자열, 1 int). – mgilson

+0

@mgilson : 네 말이 맞아, 내가 바꿀거야. –

+0

완벽한 답변, 충분히 감사 할 수 없습니다 –

3

정확한 압축 형식에 신경 쓰지 않는다면 zlib.compresszlib.decompress을 참조하십시오. zlib은 단일 문자열을 압축 할 수있는 Python 라이브러리로 자체 구현 압축 알고리즘보다 압축률이 높습니다.

+0

+1 이것은 매우 사실입니다. –

+2

zlib는 치아가 길어지고 있습니다. bz2는 빈번하게 압축되고 표준 라이브러리에 있습니다. xz/lzma가 붙잡고 있지만 Python 3.3까지는 표준 라이브러리를 만들지 못했다고 생각합니다. 그러나 구형 Python의 경우 타사 라이브러리로 사용할 수 있습니다. – user1277476

1

사용하여 정규 표현식 :

s = '1254,,,,,,,,,,,,,,,,982' 

import re 
c = re.sub(r'(.)\1+', lambda m: '(%s%d)' % (m.group(1), len(m.group(0))), s) 
print C# 1254(,16)982 

itertools에게

import itertools 
c = '' 
for chr, g in itertools.groupby(s): 
    k = len(list(g)) 
    c += chr if k == 1 else '(%s%d)' % (chr, k) 
print C# 1254(,16)982 
관련 문제