原文作者:Andrew Dalke 中文编译:Tony (digitalsatori) 问题 Python的字符串对象既可以保存文本也可以保存任意字节码。如何确定某个字符串保存了何种内容? 解决办法 我可以借鉴Perl的试探法来解决该问题。如果一个字符串包含任何空字符,或者如果其超过30%的字符拥有高位码(大于126的编码)或一些特殊控制字符,那么我们确定此字符串包含二进制编码。 from __future__ import division # ensure / does NOT truncate import string text_characters = "".join(map(chr, range(32, 127))) + "\n\r\t\b" _null_trans = string.maketrans("", "") def istext(s, text_characters=text_characters, threshold=0.30): # if s contains any null, it's not text: if "\0" in s: return False # an "empty" string is [...]
原文作者:Jurgen Hermann, Nick Perkins, Peter Cogolo 中文编译:Tony (digitalsatori) 问题 给定一个字符集合,如何创建一个过滤功能,使其作用于任意的字符串s,返回一个字符串其只包含指定字符集合中的字符。 解决方法 字符串对象的translate方法是一个处理这类问题的快速,有效的方法。但是要让translate来完成这类任务,我们还需要事先做一些准备工作。translate的第一个参数是翻译表。在我们以上的问题中并不涉及任何翻译,所以我们必须让第一个参数表示“不翻译”。translate的第二个参数表示那些字符我们要删除。因为在上述问题中,我们被要求保留而不是删除指定的字符。所以我们必须要给予第二个参数所有非保留的字符,用以被删除。closure 是做这种预先准备工作的最佳选择: import string # 创建一个代表所有字符的可重用的字符串,其作用是 # 作为一个"不做任何翻译"的翻译对照表 allchars = string.maketrans('','') def makefilter(keep): """返回一个函数,该函数以一个字符串为输入参数,运行 后返回一个仅包含'keep'中的字符的字符串拷贝。 注意:'keep' 必须是普通字符串, 不能是Unicode字符串 """ #创建一个包含除'keep'中字符以外的所有字符的字符串: #keep的反集,表示我们要删除的那些字符 delchars = allchars.translate(allchars, keep) def thefilters(s): return s.translate(allchars, delchars) return thefilters if __name__ == '__main__': just_vowels = makefilter('aeiou') print just_vowels('four score and seven [...]
原文作者:Chris Perkins, Raymond Hettinger 中文编译:Tony(digitalsatori) 问题 想使用Python字符串对象强大的 translate 方法,却总困惑于其参数的设置和 string.maketrans 的用法。怎么才能有效的简化使用呢? 解决方法 在 Python食谱1.10 中介绍的字符串的 translate 方法强大而又灵活,但是我们绝对有必要为它创建一个简化使用的用户界面。一个factory函数,返回一个closure就能轻松化繁为简: import string def translator(frm='', to='', delete='', keep=None): if len(to) == 1: to = to * len(frm) trans = string.maketrans(frm, to) if keep is not None: allchars = string.maketrans('','') delete = allchars.translate(allchars, keep.translate(allchars, delete)) def translate(s) return s.translate(trans, delete) [...]
原文作者:Jurgen Hermann, Horst Hansen 中文编译:Tony(digitalsatori) 问题 如何检查一个集合(Set)中的任意一个字符是否包含在一个字符串中 解决方法 下面是一个简单,清晰,又通用的实现方法(它可以适用于任何“序列”,而不仅限于字符串,同时也支持任何可以检测其成员的容器对象,而不仅针对集合(Set): def containsAny(seq, aset): """检查序列seq中是否包含aset的任何一个成员对象""" for c in seq: if c in aset: return True return False 你还可以利用itertools标准库模块,来构造与上述方法等效的高阶的,较复杂的方法。这种方法比上述的方法速度上要快一些: import itertools def containsAny(seq,aset): for item in itertools.ifilter(aset.__contains__, seq): return True return False 讨论 大多数与集合相关的问题最好使用Python2.4以后引入的内置类型set。(如果你使用Python2.3你可以使用其标准库中等效的sets.Set类型)但是,凡事皆有例外。比如上面的问题用纯粹的基于set的方法来处理,会是这样的: def containsAny(seq, aset): return bool(set(aset).intersection(seq)) 但是使用这种方法,seq中的每个成员都不可避免的要被全部测试。而在解决方法中的方法则会在找到答案后立即返回,不必遍历所有的成员。这对于处理一个非常长的序列来说就很重要了。 解决方法中的的第一个版本简单,清晰。第二个方法则显得“机巧”,在Python世界里这绝对不是一个赞誉之词。Python的核心价值体现在简单,清晰。但是,第二个版本也非常值得考虑。因为它是基于标准库中itertools模块的高阶实现方法。高阶实现方法多数情况下优于低阶实现方法(当然实际应用中还是要就事论事)。 itertools.ifilter 将一个‘判断‘(predicate)和一个可遍历对象(iterable)作为其参数,并且当'可遍历对象'中的成员满足'判断'时yield该成员对象。在本例中我们用 aset.__contains__ 来作为“判断”。所以,只要 ifilter 能yield任何值,它yield是seq中的某个成员对象,并且其同时也是aset中的成员。 什么是"判断“(Predicate)? [...]













