(翻译)30天学习Python👨‍💻第十二天——Lambda表达式和推导式

531 阅读2分钟

30天学习Python👨‍💻第十二天——Lambda表达式和推导式

函数式编程本身是一个很大的主题,其中有很多的概念需要理解和掌握。然而,我有一个明确的目标是30天学习Python,所以我更愿意去理解核心的概念,学习那些在开发实际项目时能够用得上的技术。

昨天我探讨了函数式编程的基本原则以及如何在Python中实现它们。今天我探索了剩下的部分,我有了非常有趣的发现,我将在这篇文章中分享。

Lambda表达式

Lambda实际上是一个计算机科学中的术语,它的意思是一个匿名函数,只在表达式执行时运行一次。Lambda表达式对简化代码非常的有用,它使函数更加简洁。但是,在复杂的表达式中过度的使用它们会使代码缺少可读性。每一个强大的东西都需要权衡使用

通过研究它们的语法和用法,立即让我想到了JavaScipt中的箭头函数,尽管它们并不是非常的相似。

names = ['John', 'Peter', 'Elon', 'Joseph']

# 使names的元素都变为大写
uppercased = list(map(lambda name: str.upper(name), names))

print(uppercased)

lambda接受任意数量的参数(在这里是name)和包含参数的表达式(这里是str.upper(name))。

users = [('Mary', 23), ('Emilie', 10), ('Katie', 30)]

sorted_by_name = sorted(users)
print(sorted_by_name) 
# [('Emilie', 10), ('Katie', 30), ('Mary', 23)]

sorted_by_age = sorted(users, key = lambda item: item[1]) 
# using age as key for sorting 

print(sorted_by_age)
# [('Emilie', 10), ('Mary', 23), ('Katie', 30)]
scores = [23, 55, 20, 90, 34, 53]

scores_under50 = list(filter(lambda x: x < 50, scores))
print(scores_under50) # [23, 20, 34]

推导式

推导式是Python里另外一种很棒的特性,非常有用。它们用于在简短的语法中快速构建例如listsetdict这样的数据结构,据说比用循环构建相同的数据结构要快。

使用推导式代替循环的想法是非常吸引人的。但是,简洁的代码并不一定可读性强。所以一行冗长的推导式应该避免,它可能看起来很简洁,但却可能会伤了某人(其他读代码的人)的心。

列表推导式

假设我们需要将一个字符串变得一个列表,最简单的方法看起来可能是这样的

name = 'python'

new_list = []
for character in name:
  new_list.append(character)

print(new_list) 
# ['p', 'y', 't', 'h', 'o', 'n']

但是,使用列表推导式可能是更简洁

name = 'python'
new_list = [item for item in name] # 这里的item可以是任意其他的名字

print(new_list)

关于列表推导式的一篇好文章

# 快速生成一个包含10个值的列表,并求它们的平方
new_list = [item**2 for item in range(10)]
print(new_list) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

也可能在推导式中添加一个条件

numbers = [2,34,23,53,34,12,22,89]

even_numbers = [num for num in numbers if num % 2 == 0]
print(even_numbers) # [2, 34, 34, 12, 22]
brands = [
  {'name': 'Nike', 'category': 'shoes'},
  {'name': 'Reebok', 'category': 'shoes'},
  {'name': 'Tesla', 'category': 'cars'},
  {'name': 'Adidas', 'category': 'shoes'},
  ]

car_brands = [item for item in brands if item['category'] =='shoes']
print(car_brands) # 过滤掉了name为Tesla的项

集合推导式

names = ['Rick', 'Alan', 'Rick', 'Mike']
new_set = {item for item in names}

print(new_set) # {'Mike', 'Alan', 'Rick'}

字典推导式

attendance = {
    'John': True,
    'David': False,
    'Nick': True,
    'Tom': False,
    'Marie': False,
    'Nancy': True
}

students_present = {key:value for key,value in attendance.items() if value}
print(students_present)
# {'John': True, 'Nick': True, 'Nancy': True}

编码练习

从一个names列表中筛选出重复的名字,并把它们存在一个列表中。我之前在探索循环和函数时解决了这个问题,今天将尝试用新的方法。

names = [
    'Harry', 'Johnny', 'Lewis', 'Harry', 'Buck', 'Nick', 'David', 'Harry',
    'Lewis', 'Michael'
]

duplicate_names = list(set([name for name in names if names.count(name) > 1]))

print(duplicate_names) # ['Lewis', 'Harry']

这个方法只用了一行代码,看上去非常的简洁,但可读性也变差了。

无论如何,知道多种方法是有好处的。在编写实际项目时,我更喜欢冗长一些,这样的做法看上去并不聪明,但可读性更好。

这就是今天函数式编程探索的全部内容,我想我已经基本掌握了大部分的基本知识。

明天,我计划深入研究python中的装饰器。我相信那是非常有趣的。

原文链接

30 Days of Python 👨‍💻 - Day 12 - Lambda Expressions & Comprehensions