Python编程学习笔记1.1

《Python编程》学习笔记1.1

礼物

本篇承接上文,介绍列表解析、生成器表达式和map的使用,这些都是python中的强大的迭代工具。

>>> pays = [person[2] for person in people]    # 收集薪酬信息
>>> pays
[36000.0, 60000.0]

>>> pays = map((lambda x: x[2]), people)   # 同上(map是3.x中的生成器)
>>> list(pays)
[36000.0, 60000.0]

>>> sum(person[2] for person in people)  # 生成器表达式,sum为内建函数
96000.0

列表解析式可以取代内建的map()函数以及lambda,而且效率更高。


列表解析介绍

它是根据已有列表,将之转换成另一个列表从而高效创建新列表的方式。

在转换过程中,可以指定元素必须符合一定的条件,才能添加至新的列表中,这样每个元素都可以按需要进行转换。

列表解析是Python迭代机制的一种应用,它常用于实现创建新的列表,因此用在[ ]中。

但它实际上是适用于任何可迭代对象的(iterable)。

List comprehension / Dict comprehension / Set comprehension / Generator comprehension

语法:

[expression for iter_val in iterable]

[expression for iter_val in iterable if cond_expr]

实例List comprehension:

要求:列出1~10所有数字的平方。

----------------------------------------------------
1、普通方法:
>>> L = []
>>> for i in range(1,11):
            L.append(i**2)
>>> print(L)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
----------------------------------------------------
2、列表解析
>>>L = [i**2 for i in range(1,11)]
>>>print L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

要求:列出1~10中大于等于4的数字的平方。

-----------------------------------------------------
1、普通方法:
>>> L = []
>>> for i in range(1,11):
             if i >= 4:
                  L.append(i**2)
>>> print(L)
[16, 25, 36, 49, 64, 81, 100]
-----------------------------------------------------
2、列表解析
>>>L = [i**2 for i in range(1,11) if i >= 4 ]
>>>print(L)
[16, 25, 36, 49, 64, 81, 100]

要求:实现两个列表中的元素逐一配对。

1、普通方法:
>>> L1 = ['x','y','z']
>>> L2 = [1,2,3]      
>>> L3 = []
>>> for a in L1:
             for b in L2:
                 L3.append((a,b))
>>> print(L3)
[('x', 1), ('x', 2), ('x', 3), ('y', 1), ('y', 2), ('y', 3), ('z', 1), ('z', 2), ('z', 3)]
-------------------------------------------------------------------------------------------
2、列表解析:
>>> L1 = ['x','y','z']
>>> L2 = [1,2,3]
>>> L3 = [ (a,b) for a in L1 for b in L2 ]
>>> print(L3)
[('x', 1), ('x', 2), ('x', 3), ('y', 1), ('y', 2), ('y', 3), ('z', 1), ('z', 2), ('z', 3)]

更多实例:Dict comprehension / Set comprehension / Generator comprehension

dict comprehension:
交换字典的key和value
>>> dt = {'A':1,'B':2}
>>> {value:key for key,value in dt.items()}
{1: 'A', 2: 'B'}
set comprehension:
>>> s = set([1,2,4])
>>> {i**i for i in s}
set([256, 1, 4])
generator comprehension:
>>> g = (a+2 for a in range(7))
>>> for i in g:
           print(i)
2
3
4
5
6
7
8

不足: 列表解析得一个不足就是必须生成所有数据,用于创建整个列表。这可能对有大量数据的迭代有其负面效应。
解决方法:生成器表达式,通过结合列表解析和生成器解决了这个问题。


生成器表达式

通过列表解析,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。

在Python中,这种一边循环一边计算的机制,称为生成器:generator。将之与列表解析结合就是生成器表达式了。

生成器表达式并不真正地创建数字列表,而是返回一个生成器对象,此对象在每次计算出一个条目后,把这个条目"产生"(yield)出来。生成器表达式使用了"惰性计算"或称作"延时求值"的机制。

一般来说,序列过长,并且每次只需要获取一个元素时,应该考虑生成器表达式而不是列表解析

语法:

(expression for iter_val in iterable)

(expression for iter_val in iterable if cond_expr)

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[ ]改成( ),就创建了一个generator。

实例:

>>> N = (i**2 for i in range(1,8))
>>> print(N)
<generator object <genexpr> at 0x7fe4fd0e1c30>      #此处返回的是一个生成器的地址
>>> N.next()
1
>>> N.next()
4
>>> N.next()
9
>>> N.next()
16
>>> N.next()
25
>>> N.next()
36
>>> N.next()
49
>>> N.next()                #所有元素遍历完后,抛出异常StopIteration  
Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
StopIteration    

其他方法现在暂且不论。


迭代器

迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退

延迟计算或惰性求值 (Lazy evaluation)

迭代器不要求你事先准备好整个迭代过程中所有的元素。仅仅是在迭代至某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合。

可迭代对象

迭代器提供了一个统一的访问集合的接口。只要是实现了__iter__()__getitem__()方法的对象,就可以使用迭代器进行访问

  • 序列:字符串、列表、元组
  • 非序列:字典、文件
  • 自定义类:用户自定义的类实现了__iter__()__getitem__()方法的对象

创建迭代器对象

使用内建的工厂函数iter(iterable)可以获取迭代器对象:

语法:

iter(collection) -> iterator

iter(callable,sentinel) -> iterator

实例展示:

使用对象内置的__iter__()方法生成迭代器

>>>L1 = [1,2,3,4,5,6]
>>>I1 = L1.__iter__()
>>>print(I1)
<listiterator object at 0x7fe4fd0ef550>   # 返回一个迭代器地址
>>> I1.next()
1
>>> I1.next()
2
>>> I1.next()
3

使用内置工厂函数生成迭代器

>>>L1 = [1,2,3,4,5,6]
>>>I1  = iter(L1)
>>>print(I1)
<listiterator object at 0x7fe4fd0ef550>   # 返回一个迭代器地址
>>> I1.next()
1
>>> I1.next()
2
>>> I1.next()
3

说明:for循环可用于任何可迭代对象。
for循环开始时,会通过迭代协议传输给iter()内置函数,从而能够从迭代对象中获得一个迭代器,返回的对象含有需要的next()方法。

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

推荐阅读更多精彩内容

  • 本文翻译自Functional Programming Howto 本文将介绍Python中函数式编程的特性。在对...
    大蟒传奇阅读 2,598评论 4 14
  • PYTHON-进阶-ITERTOOLS模块小结转自wklken:http://wklken.me/posts/20...
    C_Y_阅读 953评论 0 2
  • 在暗无天日的郑城生活着,吃饭睡觉,周末三五好友做做脸逛逛街。偶尔那个男人的脸也会出现在马路对面的陌生人身上,一开始...
    文山南阅读 440评论 2 3
  • 案例一: 在淘宝上买鞋的时候,看见一个粉色鞋带的马丁鞋,就想当然的认为是女款的鞋。拍下来~收货,发现自己的错误。然...
    爱读书的小开心阅读 2,531评论 0 0
  • 要回答这个问题首先要清楚人从哪里来。这就回到了历史,人原来和其他动物一样,只知道打猎采摘吃饭睡觉,躲避危险,繁衍后...
    淡定_4ea1阅读 241评论 0 0