18. 再说循环~列表和循环的高级操作

在前面的课程中,我们已经学习了循环和函数的基本操作,这节内容主要针对循环和函数在项目使用过程中的一些更加有使用价值的操作进行分析和讲解

本节内容:

  • 循环部分

    • 列表构建器
    • 列表动态构建器
    • 循环操作序列对象
    • 循环迭代遍历数据
  • 函数部分

    • 函数递归
    • 参数使用函数
    • 函数中返回函数
    • 匿名函数
    • 偏函数

1. 循环操作

1.1 列表构建器

常规情况下,我们定义列表的语法如下

lix = ["列表元素列表"]

如果在某些情况下,我们要定义一个1~100的列表,是一件特别麻烦的事情,手工编码就会变得非常的繁琐,此时,我们可以使用第一种方式来进行列表的构建

lix = list(range(1, 101))
执行结果:lix = [1, 2, 3, 4, 5, 6, ......]

但是,此时如果我们想要的不是自然数,而是每个数字的平方呢?
我们可以这么做

lix = [];
for x in range(1, 101):
    lix.push(x ** 2)
执行结果:lix = [1,4,9,16,25.....]

但是通过这样的方式循环迭代比较繁琐,可以通过列表构建器来直接实现

lix = [x * x  for x in range(1, 101)]
执行结果:lix = [1,4,9,16,25.....]
# 其实列表构建器中,就是一个简单的表达式操作

同样的,在列表构建器的表达式中,可以添加简单的条件处理

lix = [x * x for x in range(1, 101) if x % 2 == 0]
执行结果:lix = [4,16,36.....]

也可以在循环过程中,来使用多层循环嵌套,实现更加复杂的效果

lix = [x + y  for x in "abc" for y in "xyz"]
执行结果:['ax', 'ay', 'az', 'bx', 'by', 'bz', 'cx', 'cy', 'cz']
1.2 列表动态构建器

但是我们通过前面的学习已经知道,这些数据都是加载到内存中的,如果列表中的数据量比较大的情况下,内存消耗是比较严重的
在某些情况下,我们只需要使用列表中的一部分数据,后面的数据并不是特别关心,如:通过列表来记录一个符合某种规则的序列,每次我们只是关心下一个数据,并不关心后面的N条数据,应该怎么做呢?比如我们需要一个奇数列表

# 常规构建器的做法
lix = [2*x + 1 for x in range(1, 101)]
# 执行结果:[1,3,5,7,9,11,13,15,17.....]
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# 常规构建器可以直接构建生成
# 但是存在问题,如果一次构建的数据量太大,会严重占用内存
# 我们在使用该列表的时候,有可能只是使用前10项
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# 使用列表动态构建器
lix = (2 * x - 1 for x in range(1, 101))
# 执行结果:print (lix) --> <generator object <genexpr> at 0x7f232e462048>
next(lix)
# 执行结果:1
next(lix)
# 执行结果:3
next(lix)
# 执行结果:5
next(lix)
# 执行结果:7
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# 列表动态构建器
# 和构建器基本没有区别,创建的时候列表中是没有数据的
# 必须通过next()函数来获取列表中的下一条数据
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1.3. 循环列表

常规循环列表的方式

lix = ["远古巫灵泽拉斯", "机械先驱维克托", "惩戒之箭维鲁斯", "龙血武姬希瓦娜"]
for x in lix:
    print(x)
执行结果:
远古巫灵泽拉斯
机械先驱维克托
惩戒之箭维鲁斯
龙血武姬希瓦娜

如果此时,我想象其他语言一样,在循环过程中操作当前正在循环的元素的下标呢?
可以通过enumerate()函数对列表进行处理

lix = ["远古巫灵泽拉斯", "机械先驱维克托", "惩戒之箭维鲁斯", "龙血武姬希瓦娜"]
for index, item in enumerate(lix):
    print(index, item)
执行结果:
0 远古巫灵泽拉斯
1 机械先驱维克托
2 惩戒之箭维鲁斯
3 龙血武姬希瓦娜
1.4. 循环字典

因为列表、元组、集合中存储的都是一个个独立的元素,对列表的循环比较简单
那么如果循环key:value键值对的字典应该怎么做呢

我们回顾一下字典中常用的一些函数
dict.items();返回字典中的每一组key:value数据
dict.keys();返回字典中的所有的key组成的集合
dict.values();返回字典中所有的value组成的列表

lid = {"远古巫灵":"泽拉斯", "机械先驱":"维克托", "惩戒之箭":"维鲁斯", "龙血武姬":"希瓦娜"}
# 通过keys()循环遍历字典的key
for k in lid.keys():
    print(k)
# 通过values()循环遍历字典的value
for v in lid.values():
    print(v)
# 通过items()循环遍历所有的字典数据
for k, v in lid.items():
    print(k, v)
1.5. 循环判断

最后我们需要补充一个非常重要的东西,通常情况,我们对于python中的序列对象可以进行循环处理,那么首先需要判断一下我们要处理的数据是不是循环,如果不是循环就会出现错误

# 循环字符串
s1 = "abc"
for x in s1:
    print(x)
# 执行结果
~a
~b
~c
# 循环整数
s2 = 100;
for x in s2:
    print(x)
# 执行结果:出现报错提示int对象不是iterable
~Traceback (most recent call last):
~File "<stdin>", line 1, in <module>
~TypeError: 'int' object is not iterable

我们看到,对于非序列对象,出现对象不是iterable的错误提示
iterable是Python中的迭代对象,序列对象一般都是迭代对象
那怎么判断一个对象是否迭代对象呢?

# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# 判断一个对象是否iterable迭代对象
# 首先通过from collections import Iterable语句来在当前
# python文件中引入collections模块中的Iterable类型
# 然后通过isinstance来判断我们要循环的对象是否Iterable对象
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
s1 = "abc",
s2 = [1,2,3,4]
s3 = (1,2,3,4)
s4 = {1,2,3,4}
s5 = {"1":"a", "2":"b", "3":"c"}
s6 = 100
执行结果
>>> isinstance(s1, Iterable)
True
>>> isinstance(s2, Iterable)
True
>>> isinstance(s3, Iterable)
True
>>> isinstance(s4, Iterable)
True
>>> isinstance(s5, Iterable)
True
>>> isinstance(s6, Iterable)
False

那这样就好办了,如果我们要遍历指定的数据,首先判断是否是迭代对象,是迭代对象我们再进行迭代操作就可以了

# 导入collections模块中的Iterable对象
from collections import Iterable
# 遍历数据
s1 = [1,2,3,4]
if isinstance(s1, Iterable):
    for x in s1:
        print(x)

s2 = 10000
if isinstance(s2, Iterable):
    for x in s2:
        print(x)
# 执行结果不会出现报错了

本节内容主要讲解了实际项目中经常用到的序列对象列表的高级使用方式,以及使用for循环进行序列对象循环遍历过程中的几种特殊的使用方式。下节内容,我们继续说另一个学过的东东~函数的高级操作方式。


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

推荐阅读更多精彩内容