原文作者:Alex Martelli 中文翻译:Tony(digitalsatori) 问题描述 如何按单词或字母反向排列一个字符串 解决方法 字符串是不可改变的(immutable),所以要反向排列就需要创建一个新的字符串。反向排列最简单的方法就是使用“步进”(step)为-1的扩展切片(extended slice)操作: revchars = astring[::-1] 如果要按单词来反向排列字符串,就要先创建一个包含所有单词的列表,反向排列该列表,再用空格将列表中的单词重新连接为字符串: revwords = astring.split() # 字符串 -> 单词列表 revwords.reverse() # 反向排列单词列表 revwords = ' '.join(revwords) # 单词列表 -> 字符串 或者,也可以用一行紧凑代码来表示: revwords = ' '.join(astring.split()[::-1] 如果要按单词反转排列字符串,同时又要保持单词间的空格不变,可以使用正则表达式: import re revwords = re.split(r'(\s+)', astring) #字符串转换为列表,包含空格 revwords.reverse() #反转列表 revwords = ''.join(revwords) #列表 -> 字符串 请注意这里的连接符必须是空字符串,因为原有的空格分隔符保留在revwords列表中。同样,我们可以使用一行紧凑代码: revwords = ''.join(re.split(r'(\s+)', [...]
原文作者:Mark Mruss 中文翻译:Tony(digitalsatori) 原文出处:http://www.learningpython.com 简介 在本文中我们将讨论Python语言中三个相关的概念:iterators, iterables 和 generators。(译者注4 ) Generators的概念很容易了解。它们是创建和返回iterator的函数。而iterator和iterables就用起来容易说起来难了。iterable对象是”可以一次返回其一个成员的容器对象1 iterator 对象表示一个数据流,当重复的调用iterator 的next()方法时,其将顺序返回数据流上的数据。当没有数据时返回一个StopIteration 异常。此时iterator 对象已被穷尽,任何对next()的继续调用,都只会导致返回StopIteration 异常。2 你可以这样来理解这两个概念之间的差别:iterable 对象可以被遍历多次,而iterator 对象只能遍历一次。总之,当每次需要遍历iterable 的数据时,iterable 创建一个iterator 对象。 注: 定义了__getitem__函数的类也可以被认为是iterables,但是这个内容不在本文讨论范围之内。 本文中我们首先讨论iterators及其最基本的概念。然后是generators, 最后我们讨论3个概念中最为宽泛的话题,iterables。 Python中的遍历操作 在Python中我们使用Iterators对象来遍历对象中的数据。例如,我们都知道如何来遍历list中的数据: my_list = [1,2,3] for num in my_list: print num 上面的代码会遍历list对象my_list,然后打印出其中所有的对象,即,1,2,3。 用这种简单透明的方法对一个序列(sequences)作遍历操作是我喜欢Python的原因之一。 根据上面的定义,list是iterables,因为你可以对它作多次的遍历操作。事实上,每次对list作遍历操作时,我们实际上用到的是list创建的listiterator这个iterator对象。 你可能还不清楚什么时候应该给一个类增加遍历支持。可是,随着你更多的接触Python, 你会发现这样的设计非常有帮助,它的一个明显的好处是代码更加清晰。使用iterators 和 generators的一个好处是,只在需要时处理每个成员对象。它不是获取所有的数据并放到一个list中,然后遍历这个list,而是在你需要使用时,才去获取每个数据。乍看起来这好象没太大的区别但是请设想如果成员数据有成千上万之多呢?或者你要获取的数据来自网络呢?一次性处理所有的数据会花费很多的时间,特别当你需要的只是开头的几个数据就更划不来了。 第一个例子 为了更深入的了解遍历操作,我们来看一个可能用到iterators的简单例子。在这个例子中我们会创建一个类,这个类接受字符串然后将每个字符转换为ASCII字节码。如果我们不用iterators,这个程序会如: Listing 1 所示: Listing 1: class ByteValue(object): def [...]
问题 如何将几个小的字符串连接成一个大的字符串。 解决办法 字符串操作符 join 能将一系列小的字符串连接成一个较大的字符串。比如下例中的 pieces 是一个其成员为字符串的列表。如果你要按顺序将列表中的所有字符串连接成一个较大的字符串,可以这样: largeString = ''.join(pieces) 如果要将存储在变量中的字符串连接在一起,可以使用字符串格式化操作符%,比如: largeString = '%s%s something %s yet more' % (small1, small2, small3) 讨论 在Python中,+操作符用以连接字符串,所以它似乎是将多个小字符串连接成大字符串的不二选择。比如有几个保存在变量中的字符串,下面的处理似乎顺理成章: largeString = small1 + small2 + ' something ' + small3 + ' yet more' 相似地,如果要处理包含小字符串的序列 pieces,如下的方法似乎也很显然: LargeString = '' for piece in pieces: largeString += piece 或者使用下面这种等效且更加紧凑,机巧的方法: import operator [...]
作者:Luther Blissett 中文翻译:Tony Gu(digitalsatori) 问题 如何将字符串的在开头和结尾部分的空格去除。 解决方法 这就是字符串对象的lstrip,rstrip和strip方法发挥作用的时候了。每个方法都不带参数,运行结果返回一个字符串对象的拷贝,并且其一侧或两侧的空格被消除。 >>> x= ' hej ' >>> print '|', x.lstrip(), '|', x.rstrip(),'|', x.strip(),'|' | hej | hej | hej | 讨论 正如你在Python食谱1.4中为了把字符串左对齐,右对齐,居中对齐而在其一侧或两侧添加空格一样,你可能需要将这些空格符号从一侧或两侧移除。因为这种需要经常发生,所以Python的字符串对象也提供了三个方法来完成这种功能。你也可以在调用这些方法时提供一个参数。这个参数是一个字符串其中包括任何需要从一侧或两侧清除的字符: >>> x = 'xyxxyy hejyx yyx' >>> print '|' + x.strip('xy')+ '|' | hejyx | 注意在上例中开头和结尾处的空格仍然保留,而在两侧的'x'和'y‘被清除。 参见 Python库函数参考手册字符串方法部分,Python食谱-1.4;java食谱3.12 网络书签
作者:Luther Blissett 中文翻译:Tony Gu(digitalsatori) 问题 如何对齐字符串:左对齐,右对齐,中间对齐 解决办法 字符串对象的lust,rjust和center方法就是为解决这类问题而设的。每个方法带一个参数,即需返回字符串的宽度。操作的结果是返回一个字符串对象的拷贝,该返回字符串可能会在开头或尾部添加有空格: >>> print '|', 'hej'.ljust(20),'|','hej'.rjust(20),'|'.center(20),'|' | hej | hej | hej | 讨论 文本的居中,左对齐,右对齐是使用的非常平凡的功能。因此,Python的字符串对象通过三个方法提供了这样的功能。在Python2.3中,填空符号只能是空格。而在Python2.4以后,空格仍然是默认的填充符号,但你可以选择性地添加另外一个用作填充符号的参数: >>> print 'hej'.center(20.'+') ++++++++hej++++++++ 参见 Python函数库参考手册字符串方法部分;Java食谱-3.5 网络书签
作者:Luther Blissett 中文翻译:Tony Gu 问题 如何判断传递给函数或方法的参数是字符串(更准确的说,是否是“类字符串”对象)? 解决方法 判断是否是字符串或Unicode对象的一个简单快速的方法是使用Python内置的isinstance和basestring: def isAString(anobj): return isinstance(anobj, basestring) 讨论 对大多数的程序员来说,解决这类问题最先想到的办法就是类型判断: def isExactlyAString(anobj): return type(anobj) is type('') 但是这种方法很不好。因为它完全忽略了Python的一个强项:平滑的基于特征的多态性。这类判断将Unicode对象,用户自定义的str子类的实例,以及其它用户自定义的“类字符串"的实例排除在外。 而菜谱中提供的这种使用Python内置函数isinstance的方法就要好得多。内置类型basestring恰好能配合这种方法。basestring是str和unicode类型的共同基类,而用户自定义的作为basestring的子类的“类字符串”类型也能被上述的方法接受。basestring实际上是一个“空的”类型,就像object,所以继承它并不费周折。 但遗憾的是,这种看起来经典的isinstance判断法却无法接受UserString实例这种明显的“类字符串”对象,要知道UserString类来自于Python标准库中的UserString模块。原因当然是因为它不是继承自basestring.如果我们要支持这样的类型,直接判断对象的行为是否与字符串类似就可以了,比如: def isStringLike(anobj): try: anobj + '' except: return False else: return True 这个isStringLike函数要比“解决方法”中的isAString方法要复杂些,运行起来也慢一些,但是它确实在接受str和Unicode对象的同时也能接受UserString类和其他“类字符串”类型的实例。 Python类型判断的的一般方法被称作“类鸭判断”:如果它走起来象鸭子,叫起来象鸭子,那么对我们来说它已经足够“类鸭”了。isStringLike函数只做到了叫得象鸭子这个程度,或许这也就足够了。如果你需要检测anobj对象更多的类字符串特征,只要简单的在try语句的表达式中添加更多相关属性判断,比如: try: anobj.lower()+anobj+ '' 按照我的经验,象isStringLike函数这样的简单判断就已经足够了。 对于类型校验(或其他校验任务)最Python式的方法就是直接尝试执行需要作的任何任务,同时检测并处理任何因为某些特殊场合而产生的错误或异常。这种方法叫做“先做再纠错”(EAFP--"It's easy to ask forgiveness than permission'")。try/except是使用这种EAFP的关键工具。一般情况下,正如本文中的例子,我们只选择使用很简单的判断任务,(比如,连接一个空字串),而不用去处理全部的对象属性(比如字符串对象所有的操作和方法)。 参见 Pyhton的函数库参考的关于isinstance和basestring的内容,和Python in a Nutshell 网络书签
作者:Luther Blissett 中文翻译: Tony Gu(digitalsatori) 问题 将字符转换为ASCII(ISO)或Unicode编码的数字编码,或反之 解决办法 内置函数ord和chr就是专为此而设的: >>> print ord('a') 97 >>> print chr(97) a 内置函数ord也可以接受长度为1的Unicode字符串,它可以返回最大到65536的Unicode编码值。如果要从Unicode的数字编码获取Unicode字符串就要用到内置函数unichr: >>>print ord(u'u2020') 8224 >>>print repr(unichr(8224)) u'\u2020' 讨论 内置函数ord, chr和unichr可以将字符或Unicode字符转变为相应的数字编码,或者相反。注意:chr(n)和str(n)的区别,这是初学者经常会混淆的: >>> print repr(chr(97)) 'a' >>> print repr(str(97)) '97' chr将参数中的整数转换并根据ASCII编码返回对应的字符,而str返回的是这个整数的10进制数的字符串。 要将一个字符串转变为字符编码值的列表,可以同时使用内置函数map和ord来完成: >>> print map(ord, 'ciao') [99, 105, 97, 111] 要将字符编码值的一个列表转换为字符串,需要使用''.join,map和chr: >>> print ''.join(map(chr, range(97, 100))) abc 参见 Python函数库参考手册关于内置函数chr,ord,unichr的内容,Python in [...]













