day9 - 推导式和函数基础
一、推导式
1、列表推导式
基本结构:
[表达式 for 变量 in 序列]
[表达式 for 变量 in 序列 if 条件语句]
[表达式 for 变量1 in 序列1 for 变量2 in 序列2 if 条件语句]
[表达式1 if 条件语句 else 表达式2 for 变量 in 序列]
- 三元表达式
list1 = [x for x in 'skaghish2097u']
print(list1)
# ['s', 'k', 'a', 'g', 'h', 'i', 's', 'h', '2', '0', '9', '7', 'u']
2、集合推导式
将列表推导式的[]
换成集合的{}
set1 = {x for x in 'skaghish2097u'}
print(set1)
# {'9', 'i', 'u', 'h', '2', 'k', '0', 'a', '7', 'g', 's'}
3、元组推导式
将列表推导式的[]
替换成tuple()
tuple1 = tuple(x for x in 'skaghish2097u')
print(tuple1)
# ('s', 'k', 'a', 'g', 'h', 'i', 's', 'h', '2', '0', '9', '7', 'u')
4、字典推导式
将列表推导式的[]
替换成
1、{表达式1: 表达式2 for 变量 in 序列}
2、dict((表达式1, 表达式2) for 变量 in 序列)
其他的多重循环、if条件语句、三元表示的条件语句都和列表一样
dict1 = {x:2*x for x in 'skagh'}
print(dict1) # {'s': 'ss', 'k': 'kk', 'a': 'aa', 'g': 'gg', 'h': 'hh'}
dict2 = dict((2*x, x) for x in 'skagh')
print(dict2) # {'ss': 's', 'kk': 'k', 'aa': 'a', 'gg': 'g', 'hh': 'h'}
推导式练习
# 练习1:写一个列表推导式,产生一个列表中的元素满足以下规律:str1,str3,str6,...,str99
new_str1 = [f'str{x}' for x in range(1, 100) if x == 1 or x % 3 == 0]
print(str1)
# ['str1', 'str3', 'str6', 'str9', 'str12', 'str15', 'str18', 'str21', 'str24', 'str27', 'str30', 'str33', 'str36', 'str39', 'str42', 'str45', 'str48', 'str51', 'str54', 'str57', 'str60', 'str63', 'str66', 'str69', 'str72', 'str75', 'str78', 'str81', 'str84', 'str87', 'str90', 'str93', 'str96', 'str99']
new_str1 = [f'str' if x == 0 else f'str{x}' for x in range(0, 100, 3)]
print(str1)
# ['str1', 'str3', 'str6', 'str9', 'str12', 'str15', 'str18', 'str21', 'str24', 'str27', 'str30', 'str33', 'str36', 'str39', 'str42', 'str45', 'str48', 'str51', 'str54', 'str57', 'str60', 'str63', 'str66', 'str69', 'str72', 'str75', 'str78', 'str81', 'str84', 'str87', 'str90', 'str93', 'str96', 'str99']
# 练习3:通过字典推导式交换一个字典的键和值
d1 = {'a': 10, 'b': 20, 'c': [30, 40]}
new_dict1 = dict((key, d1[key]) if type(d1[key]) in (list, dict, set) else (d1[key], key) for key in d1)
print(new_dict1) # {10: 'a', 20: 'b', 'c': [30, 40]}
二、函数
1、函数的定义和调用
函数是实现一个特定功能的代码的封装
1)定义:
def 函数名(形参):
说明文档
代码块
2)调用:
函数名(实参)
调用时:实参的个数要和形参一致(有默认值的情况除外)
# 练习1:定义一个函数,求n的阶乘(factorial = n! = n*(n-1)*(n-2)...*1
# 函数的定义
def factorial(n):
"""
求n的阶乘
:param n: 提供一个指定的数值n
:return: None
"""
f = 1
for x in range(1, n+1):
f *= x
print(f)
# 调用函数
factorial(10) # 3628800
2、函数的参数问题
1)参数分为位置参数和关键字参数
1)位置参数:函数名(数值1, 数值2, 数值3, …)
2)关键字参数:函数名(变量1=数值1, 变量2=数值2, 变量3=数值3, …)
两者混用时:关键字参数要在位置参数后面,位置参数要按照形参的位置一一对应,关键字参数之间位置可以随更换
# 定义函数
def func1(a, b, c):
print(f'a: {a}, b: {b}, c: {c}')
# 调用函数
# 位置参数
func1(10, 20, 30) # a: 10, b: 20, c: 30
# 关键字参数 - 关键字参数之间可以交换顺序
func1(c=10, a=20, b=30) # a: 20, b: 30, c: 10
# 两者混用 - 位置参数在前,关键字参数之间可以交换顺序
func1(10, c=20, b=30) # a: 10, b: 30, c: 20
2)参数默认值
定义函数时参数可以有默认值:def 函数名(变量1, 变量2=值1, 变量3=值2, …)
有默认值的参数必须在没有默认值参数的后面,有默认值的参数在调用时可以不传值
# 定义函数
def func1(a, b=2, c=3): # 有默认值的参数必须在没有默认值参数的后面
print(f'a: {a}, b: {b}, c: {c}')
# 调用函数
# 位置参数
func1(10, 20, 30) # a: 10, b: 20, c: 30
# 关键字参数 - 关键字参数之间可以交换顺序,有默认值参数可以不传值
func1(b=30, a=20) # a: 20, b: 30, c: 3
# 两者混用 - 位置参数在前,关键字参数在后,有默认值参数可以不传值
func1(10, c=20) # a: 10, b: 2, c: 20
3)不定长参数 - 带*、带**
1)带* - 可以同时接受多个实参,这个参数实质上是一个元组,传递的对应的实参全部变成这个元组的元素(只能使用位置参数传参)
2)带** - 可以同时接受多个实参,这个参数实质上是一个字典(只能使用关键字参数传参)
定长和不定长混用时 - 定长在前:只能用关键字参数传参
定长在后:只能用关键字参数传参
注:不定长参数可以不传参
# 带*
def func2(*a):
print(a)
func2() # ()
func2(1, 2) # (1, 2)
# 带**
def func3(**a):
print(a)
func3() # {}
func3(name='张三', age=18) # {'name': '张三', 'age': 18}
# 不定长产生和定长参数间的混用
def func4(a, *b):
print(f'a: {a}, b: {b}')
# 定长在前只能用位置参数
func4(10) # a: 10, b: ()
func4(10, 20, 30, 40) # a: 10, b: (20, 30, 40)
def func5(*a, b):
print(f'a: {a}, b: {b}')
# 定长在后只能用关键字参数
func5(10, 20, 30, b=40) # a: (10, 20, 30), b: 40
def func6(*args, **kwargs): #
print(f'args: {args}, kwargs: {kwargs}')
func6(1, 2, 3) # args: (1, 2, 3), kwargs: {}
func6(a=1, b=2, c=3) # args: (), kwargs: {'a': 1, 'b': 2, 'c': 3}
func6(10, 20, a=1, b=2, c=3) # args: (10, 20), kwargs: {'a': 1, 'b': 2, 'c': 3}
# 面试题:func(*args, **kwargs),函数func中*args, **kwargs有什么意义
"""
可以时函数的调用更灵活,
"""