Python学习之路(8)函数

茴香豆 Lv5

在本章中,你将学习编写函数。函数是带名字的代码块,用于完成具体的工作。你还会学习向函数传递信息的方式,学习如何将函数存储在被称为模块的独立文件中,让主程序文件的组织更为有序。

1.定义函数

简单的示例:

1
2
3
4
5
6
7
8
# define function
def greet_user():
'''say hello'''
print("Hello!")
# use function
greet_user()
# output:
Hello!

2.向函数传递信息

位置实参:

1
2
3
4
5
6
7
8
# define function
def greet_user(username):
'''say hello'''
print("Hello, " + username.title() + "!")
# use function
greet_user('hesse')
# output:
Hello, Hesse!

关键字实参:

1
2
3
4
5
6
7
8
# define function
def greet_user(username):
'''say hello'''
print("Hello, " + username.title() + "!")
# use function
greet_user(username='hesse')
# output:
Hello, Hesse!

参数默认值:(若无默认值,则必须进行参数传递)

1
2
3
4
5
6
7
8
9
10
# define function
def greet_user(username='tom'):
'''say hello'''
print("Hello, " + username.title() + "!")
# use function
greet_user(username='hesse')
greet_user()
# output:
Hello, Hesse!
Hello, Tom!

3.函数返回值

3.1返回简单值

1
2
3
4
5
6
7
8
9
10
# define function
def get_full_name(first_name, last_name):
'''return full name'''
full_name = first_name + ' ' + last_name
return full_name.title()
# use function
musician = get_full_name('jimi', 'hendrix')
print(musician)
# output:
Jimi Hendrix

3.2返回字典

1
2
3
4
5
6
7
8
9
10
# define function
def build_person(first_name, last_name):
'''return a person dictionary'''
person = {'first': first_name, 'last': last_name}
return person
# use function
musician = build_person('jimi', 'hendrix')
print(musician)
# output:
{'first': 'jimi', 'last': 'hendrix'}

4.传递列表

你经常会发现,向函数传递列表很有用。

4.1简单使用

将列表传递给函数后,函数就能直接访问其内容。假设有一个用户列表,我们要问候其中的每位用户。

1
2
3
4
5
6
7
8
9
10
11
12
13
# define function
def greer_users(names):
'''greet to everyone in names'''
for name in names:
msg = "Hello, " + name.title() + "!"
print(msg)
# use function
usernames = ['hannah', 'ty', 'margot']
greer_users(usernames)
# output:
Hello, Hannah!
Hello, Ty!
Hello, Margot!

4.2在函数中修改列表

将列表传递给函数后,函数就可对其进行修改。在函数中对这个列表所做的任何修改都是永久性的,这让你能够高效的处理大量的数据。(形参命名只是引用,即使实参与形参的名称不同,但都是在同一个列表上操作)

当不想要函数操作后修改列表时,只需利用 list[ : ] 复制一份列表传递给函数即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# change list in function 在函数中修改列表
def print_models(un_designs, com_models):
'''
print every design in un_designs
then put it in com_models
打印所有未打印列表的设计,并将他们放到已完成列表
'''
while unprinted_designs:
current_design = un_designs.pop()
print("Printing model: " + current_design)
com_models.append(current_design)
def show_completed_models(com_models):
'''show completed_models 显示已完成列表'''
print("\nThe following models have been printed:")
for completed_model in completed_models:
print(completed_model)
# define list
unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = []
# use function
print_models(unprinted_designs, completed_models)
show_completed_models(completed_models)
# output:
Printing model: dodecahedron
Printing model: robot pendant
Printing model: iphone case

The following models have been printed:
dodecahedron
robot pendant
iphone case

5.传递任意数量的实参

有时候,你预先不知道函数需要接受多少个实参,好在Python允许函数从调用语句中收集任意数量的实参。

1
2
3
4
5
6
7
8
9
# define function
def make_pizza(*toopings):
print(toopings)
# use function
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')
# output:
('pepperoni',)
('mushrooms', 'green peppers', 'extra cheese')

形参名 *toppings 中的星号让Python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中。(注意:Python将实参封装到一个元组中,即使函数只收到一个值也是如此)

5.1结合使用位置实参和任意数量实参

如果要让函数接收不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参收集到最后一个形参中。

1
2
3
4
5
6
7
8
9
10
11
def make_pizza(size, *toopings):
print("pizza size: ", size)
print(toopings)
# use function
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
# output:
pizza size: 16
('pepperoni',)
pizza size: 12
('mushrooms', 'green peppers', 'extra cheese')

5.2使用任意数量的关键字实参

有时候,需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。在这种情况下,可将函数编写成能够接收任意数量的键值对——调用语句提供多少就接收多少。

1
2
3
4
5
6
7
8
9
10
11
12
13
# define function
def build_profile(first, last, **user_info):
profile = {}
profile['first_name'] = first
profile['last_name'] = last
for key, value in user_info.items():
profile[key] = value
return profile
# use function
user_profile = build_profile('albert', 'einstein', location='princeton', field='physics')
print(user_profile)
# output:
{'first_name': 'albert', 'last_name': 'einstein', 'location': 'princeton', 'field': 'physics'}

形参**user_info中的两个星号让Python创建一个名为user_info的空字典,并将收到的所有键值对(除了用户已经定义的)都封装在这个字典中。

6.将函数存储在模块中

通过将函数存储在独立的文件中,可隐藏程序代码的细节,将重点放在程序的高层逻辑上。也可与其他程序员共享这些文件而不是整个程序。知道如何导入函数还能让你使用其他程序员编写的函数库。

1
2
3
4
# pizza.py
def make_pizza(size, *toopings):
print("pizza size: ", size)
print(toopings)

导入整个模块:

1
2
3
4
# import whole module
import pizza
pizza.make_pizza(16, 'pepperoni')
pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

导入模块中某个函数:

1
2
3
4
# import specific function
from pizza import make_pizza
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

给导入的函数命名:

1
2
3
4
# use other name
from pizza import make_pizza as mp
mp(16, 'pepperoni')
mp(12, 'mushrooms', 'green peppers', 'extra cheese')

导入模块中所有函数:

1
2
3
4
# import all function in module
from pizza import *
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

上述四种方法输出都是相同的:

1
2
3
4
5
# output:
pizza size: 16
('pepperoni',)
pizza size: 12
('mushrooms', 'green peppers', 'extra cheese')

7. Lambda 关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# lambda 参数: 返回表达式
items = [
("Product1", 10),
("Product2", 9),
("Product3", 12),
]

# map函数对所有items元素执行指定函数操作
x = map(lambda item: item[1], items)
for item in x:
print(x)
'''
10
9
12
'''

# filter函数对所有items元素按指定函数操作进行过滤
filtered = list(filter(lambda item: item[1] >= 10, items))
print(filtered)
'''
[
("Product1", 10),
("Product3", 12),
]
'''

# [expression for item in items]
prices = [item[1] for item in items]
filtered = [item for item in items if item[1] >= 10]

8. Array

1
2
3
4
from array import array

# typecode i->signal int
numbers = array("i", [1, 2, 3]) # 统一的数据类型

9. Set

1
2
3
4
5
6
7
8
numbers = [1, 1, 2, 3, 4]
first = set(numbers) # set
second = {1, 5} # set

print(first | second) # 或集
print(first & second) # 并集
print(first - second) # 差集
print(fitst ^ second) # 异或

10. Generation

1
2
3
4
5
6
from sys import getsizeof
# 生成器不会将所有项存储在内存中,因此无法获得正在处理的项目总数
values = (x * 2 for x in range(100000)) # 得到一个生成器
print("gen:", getsizeof(values)) # gen: 120
values = [x * 2 for x in range(100000)] # 得到一个列表
print("gen:", getsizeof(values)) # gen: 824464

11. Unpacking Operator

1
2
3
4
5
6
7
8
9
numbers = [1, 2, 3]
# * 解包操作符,解包列表或元组
numbers # [1, 2, 3]
*numbers # 1, 2, 3
# ** 解包操作符,解包字典
def linear(x, k, b=0):
return k * x + b
a = {'x': 2, 'k': 3}
print(linear(**a)) # 6 # 相当于 print(linear(x=2, k=3))

12. 练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pprint import pprint
sentence = "This is a common interview question"
char_frequency = {}
for char in sentence:
if char in char_frequency:
char_frequency[char] += 1
else:
char_frequency[char] = 1
pprint(char_frequency, width=1)

char_frequency_sorted = sorted(
char_frequency.items(),
key=lambda kv: kv[1],
reverse=True
)
print(char_frequency_sorted[0])
  • Title: Python学习之路(8)函数
  • Author: 茴香豆
  • Created at : 2022-07-03 16:40:30
  • Updated at : 2024-09-26 10:46:18
  • Link: https://hxiangdou.github.io/2022/07/03/Python_8/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments