Python的高级特性

切片

In [3]: l = list(range(100))

#取前5个元素
In [4]: l[:5]
Out[4]: [0, 1, 2, 3, 4]

#取后5个元素
In [5]: l[-5:]
Out[5]: [95, 96, 97, 98, 99]

#取第11-20的元素
In [6]: l[11:20]
Out[6]: [11, 12, 13, 14, 15, 16, 17, 18, 19]

#取前10个元素,每2个取一个
In [7]: l[:10:2]
Out[7]: [0, 2, 4, 6, 8]

#取第1-10的元素,每2个取一个
In [8]: l[1:10:2]
Out[8]: [1, 3, 5, 7, 9]

#取全部的元素,每10个取一个
In [9]: l[::10]
Out[9]: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

#取得全部元素
In [10]: l[:]

#记住最后一个元素的索引是-1
In [11]: l[-1]
Out[11]: 99

list切片

In [1]: l = ['apple', 'google', 'facebook', 'microsoft', 'linkin']

In [2]: l
Out[2]: ['apple', 'google', 'facebook', 'microsoft', 'linkin']

In [3]: l[0:3]
Out[3]: ['apple', 'google', 'facebook']

In [4]: l[:3]
Out[4]: ['apple', 'google', 'facebook']

In [5]: l[1:3]
Out[5]: ['google', 'facebook']

In [6]: l[-2:]
Out[6]: ['microsoft', 'linkin']

In [7]: l[-2:-1]
Out[7]: ['microsoft']

tuple切片

In [13]: (0, 1, 2, 3, 4, 5)[:3]
Out[13]: (0, 1, 2)

str切片

In [14]: 'apple'[:3]
Out[14]: 'app'

迭代

在Python中迭代是通过for ... in ...来实现的

In [15]: d = {'apple':'pages', 'google':'docs', 'microsoft':'word'}

In [16]: for key in d:
   ....:     print key
   ....:     
google
apple
microsoft

In [17]: for value in d.values():
   ....:     print value
   ....:     
docs
pages
word

In [18]: for k, v in d.items():
   ....:     print k,v
   ....:     
google docs
apple pages
microsoft word

列表、元组、字典和字符串都是可迭代对象
判断一个对象是否是可迭代对象,通过collections模块的Iterable来判断

In [22]: from collections import Iterable

In [23]: isinstance('123', Iterable)
Out[23]: True

In [24]: isinstance([1, 2, 3], Iterable)
Out[24]: True

In [25]: isinstance((1, 2, 3), Iterable)
Out[25]: True

In [26]: isinstance({'a':1, 'b':2, 'c':3}, Iterable)
Out[26]: True

enumerate

Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身

In [27]: for i, value in enumerate(['A', 'B', 'C']):
   ....:     print(i, value)
   ....:    
(0, 'A')
(1, 'B')
(2, 'C')

列表生成式

列表生成式有自己的特殊语法
把要生成的元素放到最前面,后跟for循环,就可以创建一个list

n [29]: [i * i for i in range(1,10)]
Out[29]: [1, 4, 9, 16, 25, 36, 49, 64, 81]

#二层循环实现全排列
In [30]: [m + n for m in 'ABC' for n in 'XYZ']
Out[30]: ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

#列出根目录下的所有文件和文件夹
In [37]: [f for f in os.listdir('/')]
Out[37]: 
['.autorelabel',
 'lib',
 'sbin',
 'proc',
 'dev',
 'lib64',
 'mnt',
 'usr',
 'etc',
 'var',
 'selinux',
 '.autofsck',
 'sys',
 'srv',
 'media',
 'tmp',
 'data',
 'boot',
 'lost+found',
 'home',
 'root',
 'opt',
 'bin']

#列表生成式使用两个变量来生成列表
In [38]: d
Out[38]: {'apple': 'pages', 'google': 'docs', 'microsoft': 'word'}

In [39]: [k + '-->' + v for k,v in d.items()]
Out[39]: ['google-->docs', 'apple-->pages', 'microsoft-->word']

#将列表中的元素全部转为小写或大写
In [42]: l = ['apple', 'google', 'facebook']

In [43]: [s.lower() for s in l]
Out[43]: ['apple', 'google', 'facebook']

In [44]: [s.upper() for s in l]
Out[44]: ['APPLE', 'GOOGLE', 'FACEBOOK']

In [45]: l.append(59)

In [46]: l
Out[46]: ['apple', 'google', 'facebook', 59]

In [47]: [s.upper() for s in l]
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-47-0e109a4f23f3> in <module>()
----> 1 [s.upper() for s in l]

AttributeError: 'int' object has no attribute 'upper'

#上面遇到列表中出现字符串和数字混合的情况,数字对象没有upper()或lower()方法
#这时需要使用判断来排除数字的情况

In [52]: l
Out[52]: ['apple', 'google', 'facebook', 59]

In [53]: [s.upper() for s in l if isinstance(s, str)]
Out[53]: ['APPLE', 'GOOGLE', 'FACEBOOK']

生成器(yield)

生成器返回一个可迭代的对象

生成器的关键字yield,与return的区别是

  • return 立即返回结果并结束函数

  • yield 返回结果并暂停函数,等待next()的下一次调用

In [1]: def my_fun():
   ...:         sum = 1
   ...:         while True:
   ...:                 sum = sum + 1
   ...:                 yield sum
   ...:         

In [2]: m = my_fun()

In [3]: m.next()
Out[3]: 2

In [4]: m.next()
Out[4]: 3

In [5]: m.next()
Out[5]: 4

In [6]: m.next()
Out[6]: 5

In [7]: my_fun()
Out[7]: <generator object my_fun at 0x2767a00>

In [8]: my_fun().next()
Out[8]: 2

In [9]: my_fun().next()
Out[9]: 2

In [10]: my_fun().next()
Out[10]: 2

上面介绍的列表生成式也可以变成生成器生成式

只需把中括号换成小括号就变成了一个生成器

In [11]: L = [x * x for x in range(10)]

In [12]: L
Out[12]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

In [13]: G = (x * x for x in range(10))

In [14]: G
Out[14]: <generator object <genexpr> at 0x2767aa0>

In [15]: G.next()
Out[15]: 0

In [16]: G.next()
Out[16]: 1

In [17]: G.next()
Out[17]: 4

生成器保存的是算法,在使用时计算结果,节省内存空间


迭代器

可以直接作用于for循环的数据类型有以下几种:

  • 集合数据类型。如list tuple dict set str

  • generator,包括生成器和带yield的generator function

这些可以直接作用于for循环的对象统称为可迭代对象Iterable

可以使用isinstance()判断一个对象是否是Iterable可迭代对象

In [20]: from collections import Iterable

In [21]: isinstance([],Iterable)
Out[21]: True

生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,最后抛出StopIteration异常,表示已经结束,无法返回下一个值

可以被next()函数调用并不断返回下一个值的对象称为迭代器Iterator

可以使用isinstance()判断一个对象是否是Iterator对象

In [24]: from collections import Iterator

In [25]: isinstance((x for x in range(10)), Iterator)
Out[25]: True

In [26]: isinstance([], Iterator)
Out[26]: False

Iterator 和 Iterable的区别

  • 生成器都是Iterator对象,但list dict等是Iterable,但不是Iterator

  • Iterator是迭代器,需要同时具备__iter__next两个方法,它们表示一个惰性计算的序列

  • Iterable是可迭代对象,列表元组等数据结构同样是可迭代对象,具备__iter__方法,但不具备next方法

使用for循环遍历可迭代对象时,for循环自动调用next()函数,并在接收到结束异常时退出循环


参考文章:http://www.liaoxuefeng.com/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,841评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,415评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,904评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,051评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,055评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,255评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,729评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,377评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,517评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,420评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,467评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,144评论 3 317
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,735评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,812评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,029评论 1 256
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,528评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,126评论 2 341

推荐阅读更多精彩内容