【Python入门】6.生成器与迭代器 & 杨辉三角排列的生成

笔记更新于2019年11月10日,
摘要:切片;迭代;列表生成器;生成器 generator;迭代器 iterator


写在前面:为了更好的学习python,博主记录下自己的学习路程。本学习笔记基于廖雪峰的Python教程,如有侵权,请告知删除。欢迎与博主一起学习Pythonヽ( ̄▽ ̄)ノ


文章目录

高级特性
切片
• 【练习】去除字符串首尾空格的函数实现
迭代
• 迭代tuple
• 迭代dict中的key
• 迭代dict中的value
• 同时迭代dict中的key和value
• 拥有迭代下标
• 判断是否为可迭代对象
• 【练习】取list中的最大最小值的函数实现
列表生成器
生成器 generator
• generator的定义
• generator的调用
• 【练习】杨辉三角排列的生成
迭代器 Iterator
• 可迭代对象 Iterable
• 迭代器 Iterator
• terable转成Iterator
补充笔记
问题记录


高级特性

切片

slice,即切片的意思。在Python中可以用切片的方式来取一个list或tuple甚至字符串的其中一部分。

>>>L = list(range(0,101))                  #创建一个0到100的list
>>>L[1:10]                                 #取索引1开始,到索引10为止但不含10的元素
[1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>>L[0:10]                                 #取索引0开始,到索引10为止但不含10的元素
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>>L[:10]                                  #如果从索引0开始取,那么0可以省略
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>>L[:]                                    #取所有元素
[0, 1, 2, 3, 4, 5...96, 97, 98, 99, 100] 

我们也可以直接取后面的元素,需要注意的是第一个元素的索引号是0,倒数第一个元素的索引号是-1。切片必须顺序取值,如L[10:1]、L[-1:-10]都是无法取值的。

>>>L[-10:-1]                               #从索引-10开始到索引-1为止但不含-1的元素
[91, 92, 93, 94, 95, 96, 97, 98, 99] 
>>>L[-10:]                                 #取最后10个元素
[91, 92, 93, 94, 95, 96, 97, 98, 99, 100]

后面再加一个冒号可以实现间隔取值,如

>>>L[:10:2]                                #从索引号0开始,每2个取1个,到索引号10为止不含10
[0, 2, 4, 6, 8] 
>>>L[:30:3]                                #从索引号0开始,每3个取1个,到索引号30为止不含30
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27] 

当然,tuple和字符串也是可以进行切片的。

>>>T=(0,1,2,3,4)                           #tuple切片
>>>T[1:3]
(1, 2) 
>>>S='abcdef'                              #字符串切片
>>>S[1:3]
bc 
【练习】去除字符串首尾空格的函数实现

利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()方法。(该练习来自廖雪峰的Python教程)

# -*- coding: utf-8 -*-
def trim(s):

    while s[:1] == ' ':
        s = s[1:]
    while s[-1:] == ' ':
        s = s[:-1] 
    return s

# 测试:
if trim('hello  ') != 'hello':
    print('测试失败!')
elif trim('  hello') != 'hello':
    print('测试失败!')
elif trim('  hello  ') != 'hello':
    print('测试失败!')
elif trim('  hello  world  ') != 'hello  world':
    print('测试失败!')
elif trim('') != '':
    print('测试失败!')
elif trim('    ') != '':
    print('测试失败!')
else:
    print('测试成功!')

迭代

Iteration,当我们用for循环来遍历list或tuple时,这种遍历就是Iteration,即迭代。
在其他语言中如c,在迭代时需要通过下标来实现,而在Python中,没有下标也能实现迭代,Python的可迭代对象有很多,如list、tuple、dict、字符串等。

• 迭代tuple
>>>T = (1, 2, 3)                                
>>>for a in T:                                  #迭代tuple
...    print(a) 
...
1
2
3
• 迭代dict中的key
>>>D = {'Ming':50, 'Hong':70, 'Lily':100}       
>>>for key in D:                                #迭代dict中的key
...    print(key)
...
Ming 
Hong 
Lily 

如果要想迭代dict中的value的话,迭代对象变为D.values(),还能用D.items()同时迭代key和value。

• 迭代dict中的value
>>>for value in D.values():                     #迭代dict中的value
...    print(value)
...
50 
70 
100 
• 同时迭代dict中的key和value
>>>for k, v in D.items():                       #同时迭代dict中的key和value
...    print(k,v)
...
Ming 50 
Hong 70 
Lily 100 
• 拥有迭代下标

如果想要和其他语言一样想要有下标,可以通过Python内置的enumerate( )函数来实现

>>>for i, a in enumerate(T):                    #同时迭代去索引和元素本身
...    print(i,a)
...
0 1 
1 2 
2 3 
• 判断是否为可迭代对象

判断一个对象是否可迭代可以通过collections模块的Iterable类型判断。(以下代码转自廖雪峰的官方网站)

>>> from collections import Iterable
>>> isinstance('abc', Iterable)                 # str是否可迭代
True
>>> isinstance([1,2,3], Iterable)               # list是否可迭代
True
>>> isinstance(123, Iterable)                   # 整数是否可迭代
False
【练习】取list中的最大最小值的函数实现

请使用迭代查找一个list中最小和最大值,并返回一个tuple:(该练习来自廖雪峰的Python教程)

# -*- coding: utf-8 -*-
def findMinAndMax(L):

    if L == []:
        return(None,None)
    else:
        max = L[0]
        min = L[0]
        for x in L:
            if max > x:
                max = c
            if min < x:
                min = x

    return (max,min)

# 测试
if findMinAndMax([]) != (None, None):
    print('测试失败!')
elif findMinAndMax([7]) != (7, 7):
    print('测试失败!')
elif findMinAndMax([7, 1]) != (1, 7):
    print('测试失败!')
elif findMinAndMax([7, 1, 3, 9, 5]) != (1, 9):
    print('测试失败!')
else:
    print('测试成功!')

列表生成器

列表生成器可通过[ ]直接构建。
我们想要生成一个列表的话可以先通过list(range(,))生成初始列表,然后在循环语句或判断语句加入条件与算法从而得到想要的列表,但这种方法有点麻烦。而列表生成器可以把这个过程用一行代码实现!如我们要生成12,22,32...102这样的数列,这样就可以:

>>>[x * x for x in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 

还能在后面加入判断条件,只算奇数的平方:

>>>[x * x for x in range(1,11) if x % 2 != 0]           #除以2取余数不为0的话即为奇数
[1, 9, 25, 49, 81] 

还能采用两层循环,生成全排列

>>>[a + b for a in 'ABC' for b in 'abc']
['Aa', 'Ab', 'Ac', 'Ba', 'Bb', 'Bc', 'Ca', 'Cb', 'Cc'] 

还能同时使用两个或多个变量,如用dict生成

>>>D={'A':'a', 'B':'b', "C":'c'}
>>>[k+'-->'+v for k, v in D.items()]
['A-->a', 'B-->b', 'C-->c'] 

生成器 generator

generator,是生产者的意思。在Python中,generator意为生成器,是一种可以一边循环一边计算的机制。相比列表生成式,generator的优点在于算法不用生成全部数列,而只生成我们需要的一部分,从而节省很多空间。

• generator的定义

generator的定义有两种方式,第一种是直接通过( )创建,这种方式与列表生成器相似,只是把[ ]换成( )。

>>>g=(x * x  for x in range(1,11))
>>>g
<generator object <genexpr> at 0x00000000023427C8>

第二种方式是通过函数的形式创建,在定义函数的过程中加入yield关键字,yield后面需生成的值,则这个函数不是一个普通的函数而是一个generator。如我们可以构建一个斐波拉契数列生成器(斐波拉契数列的例子转自廖雪峰的官方网站)

著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b 
        a, b = b, a + b 
        n = n + 1
    return 'done'

generator与函数的执行方式不一样,函数的执行方式是顺序执行,直到return返回,则退出函数。而generator的执行方式是顺序执行,直到yield返回停止,下次再调用时从上次返回的yield语句后继续执行。可见正常情况下generator是不会得到return返回值的,想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中,具体操作会在后面介绍。

• generator的调用

generator的调用不能像列表生成器和函数那样直接调用。

>>>fib(6)
<generator object fib at 0x0000000000692840> 

想要调用generator,可以用next( )

>>>next(fib(6))
1
>>>next(fib(6))
1
>>>next(fib(6))
2
>>>next(fib(6))
3
>>>next(fib(6))
5

这种方式太过繁琐,generator是可迭代对象,一般采用for...in循环来调用。

>>>for n in fib(6):
...    print(n)
...
1 
1 
2 
3 
5 
8 
【练习】杨辉三角排列的生成

(该练习来自廖雪峰的Python教程。)
杨辉三角定义如下:

          1
        1   1
      1   2   1
    1   3   3   1
  1   4   6   4   1
1   5  10  10   5   1

把每一行看做一个list,试写一个generator,不断输出下一行的list:

# -*- coding: utf-8 -*-

def triangles():
    L = [1]                      #初始排列L为[1]
    while True:    
        yield L                  #返回L
        if L == [1]:
            L = L + [1]          #在L只有一个元素时,在加[1],时排列为[1,1]
        else:
            L = [1]+[L[x]+L[x+1]for x in range(len(L)-1)]+[1]    
                                 #当排列L有两个或以上的元素时,按顺序把每两个值相加生成一个值,并在前后加[1]

n = 0
results = []
for t in triangles():
    print(t)
    results.append(t)
    n = n + 1
    if n == 10:                  #生成十行排列
        break

输出结果

[1] 
[1, 1] 
[1, 2, 1] 
[1, 3, 3, 1] 
[1, 4, 6, 4, 1] 
[1, 5, 10, 10, 5, 1] 
[1, 6, 15, 20, 15, 6, 1] 
[1, 7, 21, 35, 35, 21, 7, 1] 
[1, 8, 28, 56, 70, 56, 28, 8, 1] 
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1] 

迭代器 Iterator

• 可迭代对象 Iterable

可用for循环来迭代的对象称可迭代对象——Iterable,包括list、tuple、set、str、generator。可通过isinstance()来判断一个对象是否为可迭代对象

>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance(10, Iterable)
False
• 迭代器 Iterator

而可以被next( )函数调用不断返回下个值得对象称迭代器——Iterator,如generator。可通过isinstance()来判断一个对象是否为迭代器。

>>> from collections import Iterator
>>> isinstance((x for x in range(100)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abcd', Iterator)
False
• Iterable转成Iterator

可以通过iter()函数把Iterable转成Iterator。

>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abcd'), Iterator)
True

补充笔记

‘字符串’.lower( )函数可以把字符串变成小写。


以上就是本节的全部内容,感谢你的阅读。

下一节内容:7.高阶函数之 map( )、reduce( )、filter( )、sorted( )的用法

有任何问题与想法,欢迎评论与吐槽。

和博主一起学习Python吧( ̄▽ ̄)~*

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

推荐阅读更多精彩内容

  • 前言 这篇博客写了很久,其实写每一篇博客用的时间还是挺长的,不够这有利于自己的学习,也想分享一下。之前也说了创建了...
    GitHubClub阅读 1,325评论 1 14
  • 〇、前言 本文共108张图,流量党请慎重! 历时1个半月,我把自己学习Python基础知识的框架详细梳理了一遍。 ...
    Raxxie阅读 18,910评论 17 410
  • 家有女娃,多才多艺,主修钢琴,次修铜管,舞蹈,游泳样样在修,课业增加,如何平衡? 即将升上三年级的小...
    Sophiawen阅读 174评论 0 0
  • SPT(spanning tree protocol)是一种交换机运行的、用来解决交换网络中环路问题的数据链路层协...
    Sec小玖阅读 1,612评论 0 2
  • 波: 你好吗? 现在已经是下午七点多了。今天我可是累得够呛,刚从单位回来。忘了告诉你,这个暑假,我要在我爸的单位上...
    盛夏的果实李秀英阅读 278评论 2 3