最新消息:欢迎光临 魔力 • Python!大家可以点开导航菜单中的【学习目录】,这个目录类似图书目录,更加方便学习!

Python3萌新入门笔记(22)

Python教程 小楼一夜听春语 7813浏览 0评论

这一篇教程,我们一起了解列表推导式(List Comprehension)和lambda表达式。

第一部分,我们先来了解列表推导式。

列表推导式的官方定义:一种采用简洁的方式来处理序列中的全部或部分元素,并返回结果列表。

定义中的序列实际上是指可迭代对象。

我们先来看一个例子,创建一个整数1~6平方的列表。

示例代码:

lst = [x * x for x in range(1, 7)]  # 列表推导式:循环获取范围1~6的整数,计算乘积后添加到新列表。
print(lst)  # 显示输出结果为:[1, 4, 9, 16, 25, 36]

上方代码中,创建列表时使用了列表推导式。

后方的for循环能够从1~6的范围取出整数,前方的计算公式将取出的整数自身相乘。

每一次循环都会取出数字和计算乘积,添加到一个新的列表中。

除了迭代取出元素和设定计算方法形成列表,列表推导式还能够设置条件,满足条件的元素才能够经过计算添加到列表。

例如,我们只需要1~6中偶数的平方。

示例代码:

lst = [x * x for x in range(1, 7) if x % 2 == 0]  # 列表推导式:循环获取范围1~6的整数,符合条件时,计算乘积后添加到新列表。
print(lst)  # 显示输出结果为:[4, 16, 36]

上方代码中,我们加入了条件,当取出的元素取余2为0时,进行计算。

由此我们能够看出列表推导式的组成为:[元素(或计算方法) for循环(允许多个) if语句]

再来看个例子,从整数列表中取出小于3的元素,并从平方列表中取出对应的元素,组成算式列表。

期待显示输出结果为:[‘1²=1’, ‘2²=4’, ‘3²=9’]

示例代码:(错误示例)

number = [1, 2, 3, 4, 5, 6]  # 整数列表
square = [1, 4, 9, 16, 25, 36]  # 平方列表
lst = ['{0}²={1}'.format(str(x), str(y)) for x in number for y in square if x <= 3]
print(lst)

上方代码运行结果为:

运行的结果和我们期待的不一样。

实际上,在列表推导式中有多个循环时,会出现嵌套循环的效果,而不是同步循环的效果。

也就是说,当前面的循环取出第1个元素,后方的循环会进行一轮迭代;当前面的循环取出第2个元素,后方的循环又会进行一轮迭代;以此类推,直到前方的循环完成一轮迭代为止。(可以观察显示结果的列表元素和排列顺序)

那么,如何能够得到正确的结果呢?

我们需要增加条件,当前方循环取出元素的平方等于后方循环取出元素的时候,再添加到列表。

示例代码:(正确)

number = [1, 2, 3, 4, 5, 6]  # 整数列表
square = [1, 4, 9, 16, 25, 36]  # 平方列表
lst = ['{0}²={1}'.format(str(x), str(y)) for x in number for y in square if x <= 3 and x * x == y]
print(lst) # 显示输出结果为:['1²=1', '2²=4', '3²=9']

以上代码等同于下方代码。

示例代码:

number = [1, 2, 3, 4, 5, 6]
square = [1, 4, 9, 16, 25, 36]
lst = [] # 此部分用列表推导式替代
for x in number: # 此部分用列表推导式替代
    for y in square: # 此部分用列表推导式替代
        if x <= 3 and x * x == y: # 此部分用列表推导式替代
            lst.append('{0}²={1}'.format(str(x), str(y))) # 此部分用列表推导式替代
print(lst)

通过上方代码,大家可以看出,创建同样的列表,使用列表推导式更加简洁。

第二部分,我们再来了解lambda表达式。

lambda表达式的官方定义:一个匿名内联函数,由一个表达式组成,在函数被调用时求值。

创建lambda函数的语法: lambda [参数] : 表达式

lambda表达式可用于函数的参数。

例如,我们从一个整数列表中筛选所有的偶数,可以使用filter函数。

这个函数的参数是function和iterable,也就是1个函数和1个可迭代对象。

示例代码:

def iseven(n):  # 定义验证数字是否偶数的函数
    if n % 2 == 0:  # 判断参数是否为偶数
        return True  # 符合条件返回真值
    else:
        return False #否则返回假值

lst = list(filter(iseven, number)) # 通过函数iseven对每个number的元素进行验证,验证为真的保留,并将最终结果转换为list。
print(lst) # 显示输出结果为:[2, 4, 6]

从上面的示例中,我们能够看到函数(iseven)可以作为另外一个函数(filter)的参数,并通过这个函数对其它参数进行处理。

filter函数会把number的每一个元素作为函数iseven的参数传入,进行计算,并将返回结果。

不过这样的代码,很明显看上去有些复杂。

我们可以使用lambda表达式这种匿名函数作为参数,起到同样的作用。

number = [1, 2, 3, 4, 5, 6]  # 整数列表

lst = list(filter(lambda x: x % 2 == 0, number)) # 通过lambda表达式对每个number的元素进行验证,并将所有验证结果转换为list。
print(lst) # 显示输出结果为:[2, 4, 6]

上方代码中,每一个number的元素都会作为lambda表达式的参数(冒号前面的x)进行验证,如果符合条件(冒号后方的表达式),则会保留元素。

很显然,在这种情况下通过lambda表达式可以让代码非常简化。

本节知识点:

1、列表推导式;

2、lambda表达式。

本节英文单词与中文释义:

1、square:平方

2、even:偶数

3、comprehension:理解

4、lambda:希腊字母λ的英文名称,大名鼎鼎的游戏半条命里面的logo就是这个。

练习:

从姓名集合中筛选出姓氏为“李”的姓名。

name_set = {‘邢佳栋’, ‘李学庆’, ‘高昊’, ‘潘粤明’, ‘戴军’, ‘薛之谦’, ‘贾宏声’, ‘于波’, ‘李连杰’, ‘王斑’, ‘蓝雨’, ‘刘恩佑’,’任泉’, ‘李光洁’, ‘姜文’, ‘黑龙’, ‘张殿菲’, ‘邓超’, ‘张杰’, ‘杨坤’, ‘沙溢’, ‘李茂’, ‘黄磊’, ‘于小伟’, ‘刘冠翔’,’秦俊杰’, ‘张琳’, ‘陈坤’, ‘黄觉’, ‘邵峰’, ‘陈旭’, ‘马天宇’, ‘杨子’, ‘邓安奇’, ‘赵鸿飞’, ‘马可’, ‘黄海波’,’黄志忠’, ‘李晨’, ‘后弦’, ‘王挺’, ‘何炅’, ‘朱亚文’, ‘胡军’, ‘许亚军’, ‘张涵予’, ‘贾乃亮’, ‘陆虎’, ‘印小天’,’于和伟’, ‘田亮’, ‘夏雨’, ‘李亚鹏’, ‘胡兵’, ‘王睿’, ‘保剑锋’, ‘于震’, ‘苏醒’, ‘胡夏’, ‘张丰毅’, ‘刘翔’,’李玉刚’, ‘林依轮’, ‘袁弘’, ‘朱雨辰’, ‘丁志诚’, ‘黄征’, ‘张子健’, ‘许嵩’}

答案:(见评论1楼)

转载请注明:魔力Python » Python3萌新入门笔记(22)

头像
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网站 (可选)

网友最新评论 (11)

  1. 小楼一夜听春语
    name_set = {'邢佳栋', '李学庆', '高昊', '潘粤明', '戴军', '薛之谦', '贾宏声', '于波', '李连杰', '王斑', '蓝雨', '刘恩佑', '任泉', '李光洁', '姜文', '黑龙', '张殿菲', '邓超', '张杰', '杨坤', '沙溢', '李茂', '黄磊', '于小伟', '刘冠翔', '秦俊杰', '张琳', '陈坤', '黄觉', '邵峰', '陈旭', '马天宇', '杨子', '邓安奇', '赵鸿飞', '马可', '黄海波', '黄志忠', '李晨', '后弦', '王挺', '何炅', '朱亚文', '胡军', '许亚军', '张涵予', '贾乃亮', '陆虎', '印小天', '于和伟', '田亮', '夏雨', '李亚鹏', '胡兵', '王睿', '保剑锋', '于震', '苏醒', '胡夏', '张丰毅', '刘翔', '李玉刚', '林依轮', '袁弘', '朱雨辰', '丁志诚', '黄征', '张子健', '许嵩'}
    lst1 = [x for x in name_set if '李' in x[0]]  # 使用列表推导式获取新的列表。
    lst2 = list(filter(lambda x: x[0] == '李', name_set))  # 使用lambda表达式进行筛选,将结果转换为列表。
    print(lst1)  # 显示输出结果为:['李光洁', '李玉刚', '李学庆', '李茂', '李连杰', '李亚鹏', '李晨']
    print(lst2)  # 显示输出结果为:['李光洁', '李玉刚', '李学庆', '李茂', '李连杰', '李亚鹏', '李晨']
    
    小楼一夜听春语7年前 (2017-09-13)回复
  2. 头像
    已阅,写的很好。 😆
    走路爱走神6年前 (2018-05-25)回复
  3. 头像
    文中“filter函数会把number的每一个元素作为函数iseven的参数传入,进行计算,并将返回结"句子不完整。
    alfred36年前 (2018-06-09)回复
    • 小楼一夜听春语
      已修正,谢谢!
      小楼一夜听春语6年前 (2018-06-10)回复
  4. 头像
    能否请问下习题这里为什么是为X[0],而不是X呢?这里不是很懂
    橙子丶大魔王5年前 (2018-11-21)回复
    • 头像
      因为要查询的是“李”的姓氏,所以X[0]表达的是x字符串(名字)的第一位下标,下面lambda也是同理
      老牛新知4年前 (2019-12-31)回复
  5. 头像
    name_set = ['邢佳栋', '李学庆', '高昊', '潘粤明', '戴军', '薛之谦','李刚'] lst = list(filter(lambda x: '李' in x, name_set)) print(lst) 这样写可以吗
    song5年前 (2019-01-21)回复
    • 小楼一夜听春语
      这样中间有李也会被筛选出来
      小楼一夜听春语5年前 (2019-01-24)回复
      • 头像
        [name for name in name_set if re.match(r'李.+',name)] ['李学庆', '李连杰', '李光洁', '李茂', '李晨', '李亚鹏', '李玉刚']
        我写的好麻烦5年前 (2019-03-14)回复
  6. 头像
    请教一个百度后无法解决的问题:我自己写的代码和小楼老师贴出来的答案运行后都出现SyntaxError: Non-UTF-8 code starting with '\xe4',按网上方案加上# coding = gbk 后无效,原先编码是# -*- coding:utf-8 -*-,此外,将入门笔记(21)中的同样内容的列表替换单引号并改成字典后可以运行。想请教这可能是啥问题? 可行代码: name_set = {'邢佳栋','李学庆','高昊','潘粤明','戴军','薛之谦','贾宏声','于波','李连杰','王斑','蓝雨','刘恩佑','任泉','李光洁','姜文','黑龙','张殿菲','邓超','张杰','杨坤','沙溢','李茂','黄磊','于小伟','刘冠翔','秦俊杰','张琳','陈坤','黄觉','邵峰','陈旭','马天宇','杨子','邓安奇','赵鸿飞','马可','黄海波','黄志忠','李晨','后弦','王挺','何炅','朱亚文','胡军','许亚军','张涵予','贾乃亮','陆虎','印小天','于和伟','田亮','夏雨','李亚鹏','胡兵','王睿','保剑锋','于震','苏醒','胡夏','张丰毅','刘翔','李玉刚','林依轮','袁弘','朱雨辰','丁志诚','黄征','张子健','许嵩'} print(list(filter(lambda x: x[0] == '李', [x for x in name_set]))) 不可行代码: name_set = {'邢佳栋', '李学庆', '高昊', '潘粤明', '戴军', '薛之谦', '贾宏声', '于波', '李连杰', '王斑', '蓝雨', '刘恩佑', '任泉', '李光洁', '姜文', '黑龙', '张殿菲', '邓超', '张杰', '杨坤', '沙溢', '李茂', '黄磊', '于小伟', '刘冠翔', '秦俊杰', '张琳', '陈坤', '黄觉', '邵峰', '陈旭', '马天宇', '杨子', '邓安奇', '赵鸿飞', '马可', '黄海波', '黄志忠', '李晨', '后弦', '王挺', '何炅', '朱亚文', '胡军', '许亚军', '张涵予', '贾乃亮', '陆虎', '印小天', '于和伟', '田亮', '夏雨', '李亚鹏', '胡兵', '王睿', '保剑锋', '于震', '苏醒', '胡夏', '张丰毅', '刘翔', '李玉刚', '林依轮', '袁弘', '朱雨辰', '丁志诚', '黄征', '张子健', '许嵩'} print(list(filter(lambda x: x[0] == '李', [x for x in name_set])))
    Lo5年前 (2019-06-30)回复
    • 头像
      问题已经在QQ群里通过群友得到解决。 解决方法:如果报错提示识别不了utf-8字符,是因为py默认用acsii编码,要在脚本第二行加上utf-8编码,必须是第二行!
      Lo5年前 (2019-06-30)回复