小白学习Python的第九天

一. 来认识一下推导式

推导式是用来快速方便的产生列表或者字典的表达式
1.列表推导式

"""
1)基本结构
列表 = [表达式 for 变量 in 序列]

产生一个新的列表,列表中的元素就是每次循环对应的表达式的结果

相当于:
列表 = []
for 变量 in 序列:
    列表.append(表达式)
"""""

list1 = [10 for i in range(3)]
print(list1)   # [10, 10, 10]

list2 = [2*x for x in range(1, 4)]
print(list2)   # [2, 4, 6]
# 练习1:写出一个列表推导式,产生一个列表中的元素满足以下规律:str0, str3, str6, ...str99
list3 = [f'str{i}' for i in range(0, 100, 3)]
print(list3)
"""
2)条件结构
列表 = [表达式 for 变量 in 序列 if 条件语句]

相当于:
列表 = []
for 变量 in 序列:
    if 条件语句:
        列表.append(表达式)
"""

list4 = [x for x in range(10) if x % 2]
print(list4)   # [1, 3, 5, 7, 9]

list5 = [x for x in range(10) if x % 2 == 0]
print(list5)   # [0, 2, 4, 6, 8]
# 练习2:写出一个列表推导式,产生一个列表中的元素满足以下规律:str1, str3, str6, ...str99
# 方法一:
list6 = [f'str{i}' for i in range(1, 100) if i == 1 or i % 3 == 0]
print(list6)
# 方法二:利用三目运算符
list7 = ['str1'if x == 0 else f'str{x}'for x in range(0, 100, 3)]
print(list7)
"""
多重循环结构1:
列表 = [表达式 for 变量1 in 序列1 for 变量2 in 序列2]

相当于:
列表 = []
for 变量1 in 序列1:
    for 变量2 in 序列2:
        列表.append(表达式)


多重循环结构2:
列表 = [表达式 for 变量1 in 序列1 for 变量2 in 序列2 if 条件语句]

相当于:
列表 = []
for 变量1 in 序列1:
    for 变量2 in 序列2:
        if 条件语句:
            列表.append(表达式)
"""
list8 = [f'{x}{y}' for x in range(3) for y in 'abc']
print(list8)   # ['0a', '0b', '0c', '1a', '1b', '1c', '2a', '2b', '2c']

2.集合推导式
将列表推导式的[]变成{}

a1 = {
    
    x for x in 'hello'}
print(a1)   # {'l', 'e', 'h', 'o'}

3.元组和集合推导式
元组 - 将列表推导式的[]变成tuple()

a2 = tuple(x*2 for x in 'hello')
print(a2)   # ('hh', 'ee', 'll', 'll', 'oo')

4.字典 - a.(表达式是键值对形式)将列表推导式的[]变成{}
    - b.(表达式是有且只有两个元素的序列的时候)将其列表推导式的[]变成dict()

a3 = {
    
    x: x*2 for x in 'hello'}
print(a3)   # {'h': 'hh', 'e': 'ee', 'l': 'll', 'o': 'oo'}

a4 = dict((x, x*2) for x in 'hello')
print(a4)   # {'h': 'hh', 'e': 'ee', 'l': 'll', 'o': 'oo'}

# 练习3:通过字典推导式交换一个字典的键和值
# dic = {'a': 10, 'b': 30, 'c': 30}  ->  {10: 'a', 20: 'b', 30: 'c'}
dic = {
    
    'a': 10, 'b': 20, 'c': 30}
dic1 = {
    
    dic[key]: key for key in dic}
print(dic1)   # {10: 'a', 20: 'b', 30: 'c'}
# dic2 = dict((key, value) for key, value in enumerate(dic))
# print(dic2)

# 通过字典推导式交换一个字典的键和值,如果值是可变的在新的字典中不交换
dic = {
    
    'a': 10, 'b': 20, 'c': 30, 'd': [10, 20]}
# type(数据) == list/type(数据) == dict/type(数据) == set

# 练习4:通过字典推导式交换一个字典的键和值,如果值是可变的在新的字典中不交换
dic = {
    
    'a': 10, 'b': 20, 'c': 30, 'd': [10, 20]}
dic2 = dict((key, dic[key]) if type(dic[key]) in (list, dict, set) else (dic[key], key) for key in dic)
print(dic2)   # {10: 'a', 20: 'b', 30: 'c', 'd': [10, 20]}


二. 初见函数,了解函数的作用

"""
1.没有函数会遇到什么问题:
a.相同功能对应的代码需要重复写
b.一旦功能发生改变,需要将使用到这个功能的代码的位置全部修改

怎么解决:使用函数
"""

三. 函数基础

1.认识函数

"""
a.什么是函数
函数就是对实现某一特定功能的代码的封装。(机器)

b.函数的分类(谁定义的函数)
系统函数:python已经定义好,程序员可以直接使用的函数。例如:print、input、type、chr、ord、id、max、min、sum、sorted等(别人已经造好的机器)
自定义函数:由程序员自己定义,程序员可以自己使用或者给别人使用的函数。(自己造机器)
"""

2.定义函数(造机器)

"""
语法:
def 函数名(形参列表):
    函数说明文档
    函数体

说明:
1)def - 关键字;固定写法
2)函数名 - 程序员自己命名;
           要求:标识符、不能是关键字
           规范:字母小写,单词之间用_隔开;
                见名知义(看到函数大概知道函数的功能);
                不使用系统的函数名、类型名和模块名
3)() - 固定写法(不能省略)
4)形参列表 - 以'变量名1,变量名2,变量名3,...'的形式存
            形参的作用是将函数外部的数据传递到函数里面(如果实现函数的功能需要提供外部数据,那么这个函数就需要形参)
5)函数说明文档 - 函数的说明书;本质就是用""""""引起来
6)函数体 - 和def保持一个缩进的一条或者多条语句(至少一条);
           实现函数功能的代码段
(重点)注意:定义函数的时候不会执行函数体
"""
# 实例1:定义一个函数求任意两个数字的和
def sum_num(num1, num2):
    """
    求两个数字的和 - (函数功能说明区)
    :param num1: 提供第一个数字 - (参数说明)
    :param num2: 提供第二个数字 - (参数说明)
    :return:  - None (返回值说明)
    """
    print(num1 + num2)
# 练习1:定义一个函数,求指定数的阶乘
def factorial(num):
    """
    :param num:
    :return:
    """
    total = 1
    for i in range(1, num + 1):
        total *= i
    print(f'{num}的阶乘是:{total}')

# 练习2:写一个函数将两个字符串交叉合并
# 'abc'、'123' -> a1b2c3
# 'abc'、'12345'  -> a1b2c345
# 'abcdef'、'123' -> a1b2c3def
def merge(str1, str2):
    new_str = ''
    len1 = len(str1)
    len2 = len(str2)
    # 先交叉拼接相同长度的部分
    for i in range(min(len1, len2)):
        new_str += str1[i] + str2[i]

    # 在确定尾部
    if len1 > len2:
        new_str += str1[len2:]
    else:
        new_str += str2[len1:]
    print(new_str)

3.调用函数(使用机器)

"""
语法:
函数名(实参列表)

说明:
函数名 - 需要使用的已经定义好的函数的函数名
() - 固定写法
实参列表 - 以'数据1,数据2,数据3,...'的形式存在;
          实参就是需要从函数外部传递到函数内容使用的具体的数据(默认情况下被调用的函数有多少个形参就需要提供多少个实参)
"""
sum_num(90, 10)   # 100
# 同一个函数可以调用多次
sum_num(11.1, 22.2)   # 33.3

factorial(5)   # 5的阶乘是:120

merge('abc', '123')   # a1b2c3

四. 函数的参数

1.位置参数和关键字参数
根据实参的传递方式将实参分为位置参数和关键字参数两种

"""
1)位置参数
以'实参1,实参2,实参3,...'形式存在,让实参和形参一一对应

2)关键字参数
以'形参1=实参1,形参2=实参2,...'形式存在,这个参数的位置可以随意更改

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(a=100, b=200, c=300)   # a:100, b:200, c:300
func1(b=200, a=100, c=300)   # a:100, b:200, c:300

# 混用
func1(10, 20, c=30)   # a:10, b:20, c:30
func1(100, c=200, b=150)   # a:100, b:150, c:200

# func1(400, 500, a=100)   # TypeError: func1() got multiple values for argument 'a'
# func1(a=100, 200, 300)   # SyntaxError: positional argument follows keyword argument

2.参数默认值

"""
定义函数的时候可以直接给一个或者多个形参赋默认值;有默认值的参数在调用的时候可以不传参。
"""
def func2(a=1, b=2, c=3):
    print(f'a:{a}, b:{b}, c:{c}')


func2()   # a:1, b:2, c:3
func2(10, 20)   # a:10, b:20, c:3
func2(b=15)   # a:1, b:15, c:3


def func3(a, b, c=3):
    print(f'a:{a}, b:{b}, c:{c}')


# func3()   # TypeError: func3() missing 2 required positional arguments: 'a' and 'b'
func3(100, 200)   # a:100, b:200, c:3
func3(100, 200, 300)   # a:100, b:200, c:300


# def func4(a, b=2, c):
#     print(f'a:{a}, b:{b}, c:{c}')   # SyntaxError: non-default argument follows default argument

# 有默认值的参数必须放在没有默认值参数的后面
def func4(a, c, b=2):
    print(f'a:{a}, b:{b}, c:{c}')


func4(1, 3)   # a:1, b:2, c:3

3.不定长参数

"""
定义函数的时候如果参数个数不确定,可以使用不定长参数

1)带*的不定长参数
在形参前加一个*,让这个形参变成不定长参数,可以同时接收多个实参。这个参数的本质就是一个元组,传递的对应的实参全部会变成这个元组中的元素
(必须使用位置参数传参)

2)带**的不定长参数
在形参前加**让这个形参变成不定长参数,可以同时接受多个实参。这个参数的本质就是一个字典(必须使用关键字参数传参,关键字自己随意命名)
"""
# 定义一个函数,求多个数的平均值
def mean(*num):
    if len(num) == 0:
        print('0')
    else:
        print(sum(num)/len(num))


mean()   # 0
mean(10, 54, 64, 78, 90)   # 59.2


# 这儿的x必须使用位置参数传参
def func6(x, *a):
    print('x:', x, 'a:', a)


func6(20)   # x: 20 a: ()
func6(10, 20, 30, 40)   # x: 10 a: (20, 30, 40)


# 这儿的x必须使用关键字参数传参
def func7(*a, x):
    print('x:', x, 'a:', a)


func7(1, 2, 3, 4, x=100)   # x: 100 a: (1, 2, 3, 4)


def func8(**num):
    print(num)


func8()   # {}
# func8(10)   # TypeError: func8() takes 0 positional arguments but 1 was given
func8(a=100)   # {'a': 100}
func8(name='张三', age=30)   # {'name': '张三', 'age': 30}


# 面试题:func(*args, **kwargs),函数中*args,**kwargs有什么意义
# 让这个函数调用的时候更加灵活

猜你喜欢

转载自blog.csdn.net/bbbbbya/article/details/108983306