文章来自《Python cookbook》. 翻译仅仅是为了个人学习,其它商业版权纠纷与此无关!
-- Zoom.Quiet [DateTime(2004-08-11T01:12:01Z)] TableOfContents
拉平一个嵌套的序列
1.13 Flattening a Nested Sequence
Credit: Luther Blissett
问题 Problem
You have a sequence, such as a list, some of whose items may in turn be lists, and so on. You need to flatten it out into a sequence of its scalar items (the leaves, if you think of the nested sequence as a tree).
你有一个序列, 例如一个list, 或许它的元素中的一些依次是list等等.你需要把它的元素按照它的标量展开到一个序列中去
解决 Solution
Of course, we need to be able to tell which of the elements we're handling are to be deemed scalar. For generality, say we're passed as an argument a predicate that defines what is scalar梐 function that we can call on any element and that returns 1 if the element is scalar or 0 otherwise. Given this, one approach is: 当然,我们需要能够告诉,我们正在处理的元素的那些是被考虑作为标量的。一般来说,假定我们传递一个定义了标量函数的谓词【译注:它很象stl库里的predicate的概念。一个函数指针作为参数被传递】作为参数,这个函数我们能够在任何一个元素上调用并且如果元素是标量,返回1,否则返回0。一个方法是: def flatten(sequence, scalarp, result=None): if result is None: result = [] for item in sequence: if scalarp(item): result.append(item) else: flatten(item, scalarp, result) return result
In Python 2.2, a simple generator is an interesting alternative, and, if all the caller needs to do is loop over the flattened sequence, may save the memory needed for the result list: 在python2.2,一个简单的产生器是一个有趣的选择。并且,如果所有的调用要做的是需要在平坦序列上循环,可以为计算结果的list存储所需要的内存
from _ _future_ _ import generators def flatten22(sequence, scalarp): for item in sequence: if scalarp(item): yield item else: for subitem in flatten22(item, scalarp): yield subitem
讨论 Discussion
The only problem with this recipe is that determining what is a scalar is not as obvious as it might seem, which is why I delegated that decision to a callable predicate argument that the caller is supposed to pass to flatten. Of course, we must be able to loop over the items of any non-scalar with a for statement, or flatten will raise an exception (since it does, via a recursive call, attempt a for statement over any non-scalar item). In Python 2.2, that's easy to check: 这个配方的一个问题是, 【决定一个标量是什么】似乎不是象它一样明显。那就是为什么我决定委托一个可调用的谓词参数,它的调用者被假定平坦传递的。 当然,我们必须能够使用for语句在任何非标量的元素上循环,或者平坦化将引发一个异常(因为,它通过一个递归调用,企图让for语句作用在任何非标量条目上)
def canLoopOver(maybeIterable): try: iter(maybeIterable) except: return 0 else: return 1
The built-in function iter, new in Python 2.2, returns an iterator, if possible. for x in s implicitly calls the iter function, so the canLoopOver function can easily check if for is applicable by calling iter explicitly and seeing if that raises an exception. å 建ç彿°iter,å¨python2.2䏿¯æ°çï¼å¦æå¯è½ï¼å®è¿åä¸ä¸ªiteratorãfä¸å¾ªç¯ï¼å¯ä»¥ä¸ºè®¡ç®ç»æçlistå卿éè¦çå å
from _ _future_ _ import generators def flatten22(sequence, scalarp): for item in sequence: if scalarp(item): yield item else: for subitem in flatten22(item, scalarp): yield subitem
讨论 Discussion
The only problem with this recipe is that determining what is a scalar is not as obvious as it might seem, which is why I delegated that decision to a callable predicate argument that the caller is supposed to pass to flatten. Of course, we must be able to loop over the items of any non-scalar with a for statement, or flatten will raise an exception (since it does, via a recursive call, attempt a for statement over any non-scalar item). In Python 2.2, that's easy to check: è¿ä¸ªé æ¹çä¸ä¸ªé®é¢æ¯ï¼ ãå³å®ä¸ä¸ªæ 鿝ä»ä¹ãä¼¼ä¹ä¸æ¯è±¡å®ä¸æ ·ææ¾ãé£å°±æ¯ä¸ºä»ä¹æå³å®å§æä¸ä¸ªå¯è°çor x in séå«çè°ç¨iter彿°ãæä»¥canLoopOver彿°è½å¤å¾å®¹æçéè¿æ¾å¼çè°ç¨iteræ£æ¥æ¯å¦foræ¯åéçå¹¶ä¸çæ¶åæåºä¸ä¸ªå¼å¸¸ã
In Python 2.1 and earlier, there is no iter function, so we have to try more directly: 在python2.1和更早的版本,没有iter函数。所以我们不得直接try更多的东西。
def canLoopOver(maybeIterable): try: for x in maybeIterable: return 1 else: return 1 except: return 0
Here we have to rely on the for statement itself raising an exception if maybeIterable is not iterable after all. Note that this approach is not fully suitable for Python 2.2: if maybeIterable is an iterator object, the for in this approach consumes its first item. è¿å¿ï¼å¦æmaybeIterableæ ¹æ¬ä¸æ¯å¯è¿ä»£çï¼æä»¬ä¸å¾ä¸ä¾èµäºforè¯å¥èªå·±æåºä¸ä¸ªå¼å¸¸ã注æï¼è¿ä¸ªæ¹æ³ä¸æ¯å®å ¨éç¨äºpython2.2ã 妿maybeIterableæ¯ä¸ä¸ªè¿ä»£å¯¹è±¡ï¼forå¨è¿ä¸ªæ¹æ³éæ¶çæç¬¬ä¸ä¸%APOST http://wiki.woodpecker.org.cn/moin.cgi/PyCkBk_2d1_2d13 HTTP/1.0 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */* Referer: http://wiki.woodpecker.org.cn/moin.cgi/PyCkBk_2d1_2d13?action=edit