【问题标题】:TEXT compression in pythonpython中的文本压缩
【发布时间】:2011-01-30 19:17:33
【问题描述】:

我有这段文字:

2,3,5,1,13,7,17​​,11,89,1,233,29,61,47,1597,19,37,41,421,199,28657,23,3001,521,53,281,514229,31,557 ,2207,19801,3571,141961,107,73,9349,135721,2161,2789,211,433494437,43,109441,139,2971215073,1103,97,101,6376021,907661,953,0579, ,59,353,2521,4513,3010349,35239681,1087,14736206161,9901,269,67,137,71,6673,103681,9375829,54018521,230686501,29134601,988681,79,157,1601,2269,370248451,99194853094755497,83,9521 ,6709,173,263,1069,181,741469,4969,4531100550901,6643838879,761,769,193,599786069,197,401,743519377,919,519121,103,8288823481,119218851371,1247833,11128427,827728777,331,1459000305513721,10745088481,677,229,1381 ,347,29717,709,159512939815855788121,

这是从我的生成器程序生成的数字,现在问题有源代码限制,所以我不能在我的解决方案中使用上述文本所以我想压缩它并将其放入python中的数据结构,以便我可以通过以下索引来打印它们:

F = [`compressed data`]

F[0] 会给出2 F[5] 会给出7 像这样...请给我推荐一种合适的压缩技术。

PS:我是python的新手,所以请解释一下你的方法。

【问题讨论】:

  • 我在这里看不到任何压缩。你确定这就是你的意思吗?
  • 压缩?这并不意味着你认为它意味着什么。
  • 您的号码列表的大小是多少?您需要多快获取索引编号?这个数字列表是否有任何关于数字序列的边界、属性、特征或任何其他信息?你说你有源代码限制。它是什么?你有内存限制吗?有多种压缩算法,正确的选择取决于您的限制和可用信息。
  • 给定一个值 N 我已经输出了 F[N] 的值,现在 F[] 的初始化应该是 F = [ 2,3,5,1,13,7,17​​, 11,89,1,233,...] 但我使用压缩值而不是数字,这样整个源代码限制就足够了。
  • @Tretwick Marian:您能否详细说明the problem has a source code limitcan't use the above texts in my solution 的含义。您是否参加某种编码比赛?顺便说一句,您是否考虑过将“文本”保存到文件中,稍后在需要时将其读取到列表中?

标签: python text-compression


【解决方案1】:

当然可以:

import base64
import zlib
compressed = 'eJwdktkNgDAMQxfqR+5j/8V4QUJQUttx3Nrzl0+f+uunPPpm+Tf3Z/tKX1DM5bXP+wUFA777bCob4HMRfUk14QwfDYPrrA5gcuQB49lQQxdZpdr+1oN2bEA3pW5Nf8NGOFsR19NBszyX7G2raQpkVUEBdbTLuwSRlcDCYiW7GeBaRYJrgImrM3lmI/WsIxFXNd+aszXoRXuZ1PnZRdwKJeqYYYKq6y1++PXOYdgM0TlZcymCOdKqR7HYmYPiRslDr2Sn6C0Wgw+a6MakM2VnBk6HwU6uWqDRz+p6wtKTCg2WsfdKJwfJlHNaFT4+Q7PGfR9hyWK3p3464nhFwpOd7kdvjmz1jpWcxmbG/FJUXdMZgrpzs+jxC11twrBo3TaNgvsf8oqIYwT4r9XkPnNC1XcP7qD5cW7UHSJZ3my5qba+ozncl5kz8gGEEYOQ'
data = zlib.decompress(base64.b64decode(compressed))

请注意,这仅短了 139 个字符。 但它有效:

>>> data
'2,3,5,1,13,7,17,11,89,1,233,29,61,47,1597,19,37,41,421,199,28657,23,3001,521,53,281,514229,31,557,2207,19801,3571,141961,107,73,9349,135721,2161,2789,211,433494437,43,109441,139,2971215073,1103,97,101,6376021,90481,953,5779,661,14503,797,59,353,2521,4513,3010349,35239681,1087,14736206161,9901,269,67,137,71,6673,103681,9375829,54018521,230686501,29134601,988681,79,157,1601,2269,370248451,99194853094755497,83,9521,6709,173,263,1069,181,741469,4969,4531100550901,6643838879,761,769,193,599786069,197,401,743519377,919,519121,103,8288823481,119218851371,1247833,11128427,827728777,331,1459000305513721,10745088481,677,229,1381,347,29717,709,159512939815855788121,'

如果您的代码限制真的很短,也许您应该计算这些数据或其他什么?这是什么?

【讨论】:

  • 您是如何以编程方式获得压缩值的? :)
  • 我做了同样的事情,但相反。
  • 好吧,让我试着改写一下:) 我想知道你是如何获得这种格式的压缩值的?因为像 ideone.com/EDftR 这样的东西没有给我这个价值。
  • 是的,我说的是reverse。您显然必须颠倒操作的顺序,即base64.b64encode(zlib.compress(s))
  • 我对这个投了赞成票 :) 现在我理解了这两种解决方案 :)
【解决方案2】:

zlib 可以完成工作,如果您确实想要压缩。如果你不想压缩,那我的读心能力恐怕会下降。

【讨论】:

  • gzip + base64 的大小可能确实比源文本小。我只是尝试使用显示的数字来做到这一点,并将文本从 663 字节压缩到 475 字节。不过,不是很出色。
  • 我想这就是我要找的东西,但我是 pyth 的新手,所以请解释一下压缩和解压缩技术吗?
  • @Tretwick 压缩使其占用的空间更少。 zlib 是无损压缩,因此不会丢失任何信息。解压是逆运算。您是否阅读了我在答案中包含的链接?
  • 是的,我做了,说我想压缩一个文本'我的名字是 Tretwick',因此我写 zlib.compress('My name is Tretwick') 但是我必须打印它然后才能得到将压缩数据返回以获取原始数据我必须使用 zlib.decompress() 但是当我打印它时,它会给我一些不同的东西,如果我将粘贴复制到解压缩模块中,这些东西就不起作用。我希望你明白我的意思。
  • @Tretwick 我猜你做错了,但我不知道我的头。您建议的简单压缩/解压缩循环对我来说很好。
【解决方案3】:

在 Python 2.4-2.7 上,pypy、jython:

>>> enc = sdata.encode('zlib').encode('base64')
>>> print enc
eJwdktkNgDAMQxfqR+5j/8V4QUJQUttx3Nrzl0+f+uunPPpm+Tf3Z/tKX1DM5bXP+wUFA777bCob
4HMRfUk14QwfDYPrrA5gcuQB49lQQxdZpdr+1oN2bEA3pW5Nf8NGOFsR19NBszyX7G2raQpkVUEB
dbTLuwSRlcDCYiW7GeBaRYJrgImrM3lmI/WsIxFXNd+aszXoRXuZ1PnZRdwKJeqYYYKq6y1++PXO
YdgM0TlZcymCOdKqR7HYmYPiRslDr2Sn6C0Wgw+a6MakM2VnBk6HwU6uWqDRz+p6wtKTCg2WsfdK
JwfJlHNaFT4+Q7PGfR9hyWK3p3464nhFwpOd7kdvjmz1jpWcxmbG/FJUXdMZgrpzs+jxC11twrBo
3TaNgvsf8oqIYwT4r9XkPnNC1XcP7qD5cW7UHSJZ3my5qba+ozncl5kz8gGEEYOQ
>>> print enc.decode('base64').decode('zlib')[:79]
2,3,5,1,13,7,17,11,89,1,233,29,61,47,1597,19,37,41,421,199,28657,23,3001,521,53
>>> sdata == enc.decode('base64').decode('zlib')
True
>>> F = [int(s) for s in sdata.split(',') if s.strip()]
>>> F[0], F[5]
(2, 7)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    • 2019-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多