python 中迭代多个序列

http://blog.csdn.net/he_jian1/article/details/40819407

一、多个序列迭代

有时候我们希望能够同时遍历多个序列,比如有序列a = [1, 2, 3, 4, 5], b = ['a', 'b', 'c', 'd', 'e'],我们如果要同时遍历的话,可以采用如下的方式:

  1. >>> xpts = [1, 5, 4, 2, 10, 7]  
  2. >>> ypts = [101, 78, 37, 15, 62, 99]  
  3. >>> for x, y in zip(xpts, ypts):  
  4. ...     print(x, y)  
  5. ...   
  6. 1 101
  7. 5 78
  8. 4 37
  9. 2 15
  10. 10 62
  11. 7 99

  因为使用了zip()方法,我们将两个集合里的内容都同时取出来,按照tuple的方式一个个的组织起来。所以我们访问的时候也是通过一个个tuple的方式来读取。这里我们提供的两个list是长度一致的,如果不一致会怎么样呢?我们再来试试另外两个序列:

  1. >>> a = [1, 2, 3, 4]  
  2. >>> b = ['a', 'b', 'c']  
  3. >>> for x, y in zip(a, b):  
  4. ...     print(x, y)         
  5. ...   
  6. 1 a  
  7. 2 b  
  8. 3 c  

从代码运行的结果来看,默认是遍历到短的那个序列结束。如果我们需要到那个长的序列结束呢?这里有另外一种办法:

Python代码  

  1. >>> from itertools import zip_longest  
  2. >>> for i in zip_longest(a, b):  
  3. ...     print(i)  
  4. ...   
  5. (1, 'a')  
  6. (2, 'b')  
  7. (3, 'c')  
  8. (4, None)  

    这里引用了zip_longest方法,它可以将两个序列组合起来,不过对于短的那个序列,用None来补齐。

将几个序列串在一起

    我们可以直接看如下的代码:

Python代码  

  1. >>> from itertools import chain  
  2. >>> a = [1, 2, 3, 4]  
  3. >>> b = ['a', 'b', 'c']  
  4. >>> for x in chain(a, b):  
  5. ...     print(x)  
  6. ...   
  7. 1
  8. 2
  9. 3
  10. 4
  11. a  
  12. b  
  13. c  

    一个chain方法就解决了大部分问题了。和我们默认想到的方法比起来,chain方法效率更加高。因为我们最开始会考虑将两个或者多个序列连在一起,比如a + b,这样会创造一个新的序列出来,这样带来的成本开销明显偏大了。

将嵌套的序列变平

    这是一个有意思的问题,因为一般来说当我们需要访问一个数组的时候,比如说a = [1, 2, [3, 4, [5, 6], 7, 8], 9, 10],我们希望能够将他们所有的元素都输出,并使得他们看起来像就是一个一维数组那样,如a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]。我们默认的思路该怎么办呢?只怕一开始就是碰到一个元素的时候会判断它是否为数组,如果是的则递归的去输出它的元素。

    Python里面有一个很强大的特性可以很好的实现这个方法:

Python代码  

  1. from collections import Iterable  
  2. def flatten(items, ignore_types=(str, bytes)):  
  3. for x in items:  
  4. if isinstance(x, Iterable) and not isinstance(x, ignore_types):  
  5. yield from flatten(x)  
  6. else:  
  7. yield x  

    这种实现里面有一个额外的ignore_types,里面列举了一些类型我们可以不需要进一步的去遍历。比如说str,我们一般碰到一个字符串可以直接将他们作为一个整的对象输出而不是再对它们进一步拆分的遍历。最有意思的地方在yield from这个部分。yield from这个部分的意思是将后续的值作为它本身的一个subroutine。所以它们就会被当作一个拉平的数组。关于yield from这部分我们在后面的文章中会专门讲述。

    按照这个方式,我们使用它们的代码如下:

Python代码  

  1. >>> from nested import flatten  
  2. >>> items = [1, 2, [3, 4, [5, 6], 7], 8]  
  3. >>> for x in flatten(items):  
  4. ...     print(x)  
  5. ...   
  6. 1
  7. 2
  8. 3
  9. 4
  10. 5
  11. 6
  12. 7
  13. 8

迭代多个有序排列数组

    这个问题不太好用一句话描述,就是说假定我们有若干个已经排序的数组了。当我们希望能够去遍历这所有的序列,但是保证我们每次都取出他们中间最小的元素,保证所有输出还是一个严格排序的结果,我们该怎么办呢?实际上,这是一个多路归并排序的问题。在前面的一些文章里有过讨论,不过要做一个好的java实现我们可是费了一番功夫。这里有什么好的招呢?

Python代码  

  1. >>> import heapq  
  2. >>> a = [1, 4, 7, 10]  
  3. >>> b = [2, 5, 6, 11]  
  4. >>> for c in heapq.merge(a, b):  
  5. ...     print(c)  
  6. ...   
  7. 1
  8. 2
  9. 4
  10. 5
  11. 6
  12. 7
  13. 10
  14. 11

    这里是归并两路的数据结果。在一些我们如果要归并多个文件的情况下,也可以这样来做。因为这里heapq.merge不是一次将所有的数据都装载到内存里,它只是每次取很小的一部分,像generator一样。所以对于大文件的合并用这种方式来做。呵呵,寥寥几行代码就解决了问题,不能不说,很好很强大啊。 

总结

    Iterator的定义方法虽然看起来很简单,但是它的使用也可以非常的复杂和灵活。通过结合一些库的支持,我们可以实现非常强大的计算效果。当然,前提是我们需要知道去哪里找到这些库和知道这些用法。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java爬坑系列

【Java入门提高篇】Day14 Java中的泛型初探

  泛型是一个很有意思也很重要的概念,本篇将简单介绍Java中的泛型特性,主要从以下角度讲解:   1.什么是泛型。   2.如何使用泛型。   3.泛型的好处...

3326
来自专栏Java Web

Java学习笔记(2)——数据类型

终于要写点干货了,其实思考了很久下面一篇文章要写什么,主要的纠结点在于,既想要分享那些精美的知识,又怕这些知识不太好嚼。后来想想还是对初学者不太好友算了..一...

2783
来自专栏和蔼的张星的图像处理专栏

55. 比较字符串

比较两个字符串A和B,确定A中是否包含B中所有的字符。字符串A和B中的字符都是 大写字母 样例 给出 A = "ABCD" B = "ACD",返回 tru...

1411
来自专栏喵了个咪的博客空间

zephir-(10)内置函数

#zephir-内置函数# ? ##前言## 先在这里感谢各位zephir开源技术提供者 嗨!大家好呀,今天要和大家一同学习zephir的内置函数,学过PHP的...

3698
来自专栏鸿的学习笔记

从Scala和Python的“shell”说起

在《写给Python和Scala的碎碎念》的系列的开篇,让我们从最简单的交互式“shell”开始,一步步来看看Python和Scala的对于同一件...

1042
来自专栏小詹同学

Leetcode打卡 | No.014 最长公共前缀

欢迎和小詹一起定期刷leetcode,每周一和周五更新一题,每一题都吃透,欢迎一题多解,寻找最优解!这个记录帖哪怕只有一个读者,小詹也会坚持刷下去的!

1022
来自专栏思考的代码世界

Python编程从入门到实践之使用字典|第6天

一个Python字典可能只包含几个键—值对,也可能包含数百万个键—值对。鉴于字典可能包含 大量的数据,Python支持对字典遍历。字典可用于以各种方式存储信息,...

3617
来自专栏java一日一条

10个有关String的面试问题

简单来讲,“==”测试的是两个对象的引用是否相同,而equals()比较的是两个字符串的值是否相等。除非你想检查的是两个字符串是否是同一个对象,否则你应该使用e...

682
来自专栏思考的代码世界

Python编程从入门到实践之条件判断|第4天

在日常开发中需要用到如果怎么样就怎么样,否则就怎么样的逻辑。主要采用if语句来实现的。

3727
来自专栏测试开发架构之路

程序员面试50题(4)—把字符串转换成整数[算法]

题目:输入一个表示整数的字符串,把该字符串转换成整数并输出。例如输入字符串"345",则输出整数345。 分析:这道题尽管不是很难,学过C/C++语言一般都能实...

41110

扫码关注云+社区

领取腾讯云代金券