使用string.translate()将不可打印的字符转换为点

Jim*_*nis 2 python code-golf

所以我之前已经完成了这个,对于这样一个看似简单的任务来说,这是一个令人惊讶的丑陋代码.

目标是将任何不可打印的角色翻译成一个.(点).出于我的目的,"可打印"确实排除了最后几个字符string.printable(换行符,制表符等).这是用于打印旧的MS-DOS调试"十六进制转储"格式......或任何类似的东西(其中额外的空格将破坏预期的转储布局).

我知道我可以使用,string.translate()并且要使用它,我需要一个翻译表.所以我用string.maketrans()它.这是我能想到的最好的:

filter = string.maketrans(
   string.translate(string.maketrans('',''),
   string.maketrans('',''),string.printable[:-5]),
   '.'*len(string.translate(string.maketrans('',''),
   string.maketrans('',''),string.printable[:-5])))
Run Code Online (Sandbox Code Playgroud)

......这是一个难以理解的混乱(虽然它确实有效).

从那里你可以打电话使用像:

for each_line in sometext:
    print string.translate(each_line, filter)
Run Code Online (Sandbox Code Playgroud)

... 而且要快乐.(只要你不看引擎盖).

现在,如果我将这个可怕的表达式分解为单独的语句,它就更具可读性:

ascii = string.maketrans('','')   # The whole ASCII character set
nonprintable = string.translate(ascii, ascii, string.printable[:-5])  # Optional delchars argument
filter = string.maketrans(nonprintable, '.' * len(nonprintable))
Run Code Online (Sandbox Code Playgroud)

为了便于阅读,这样做很诱人.

但是,我一直认为必须有一种更优雅的方式来表达这一点!

ata*_*lor 5

这是使用列表理解的另一种方法:

filter = ''.join([['.', chr(x)][chr(x) in string.printable[:-5]] for x in xrange(256)])
Run Code Online (Sandbox Code Playgroud)

  • 哦,那是邪恶的!依靠条件的 0/1 数值作为包含 '.' 的两项列表的索引。和每个字符依次。我喜欢! (2认同)