【发布时间】:2009-11-25 23:59:30
【问题描述】:
所以我以前做过这个,对于这样一个看似简单的任务,这是一个令人惊讶的丑陋代码。
目标是将任何不可打印的字符转换为 .(点)。出于我的目的,“可打印”确实排除了 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])))
...这是一个难以理解的混乱(尽管它确实有效)。
从那里你可以调用 use 类似的东西:
for each_line in sometext:
print string.translate(each_line, filter)
...开心就好。 (只要你不看引擎盖)。
现在,如果我将这个可怕的表达式分成单独的语句,它会更易读:
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))
为了易读性而这样做很诱人。
但是,我一直认为必须有一种更优雅的方式来表达这一点!
【问题讨论】:
-
你可以在你的循环中使用
each_line.translate(filter) -
我没有想到“优雅”的标签。 :((而且我看不到如何添加标签)。
-
如果代码打高尔夫球整个过程(替换所有不可打印的字符)是您的目标,那么您可以使用一个衬垫(假设
my_str是您要翻译的字符串)''.join(list(map(lambda x: ['.',x][x in set(string.printable[:-5])], my_str))但是,我可能更喜欢使用:''.join(list(map(lambda x: x if (x in set(string.printable[:-5])) else '.', my_str)))以提高清晰度