文章目录

  • 一、函数
    • 1、函数的参数
    • 2、全局变量和局部变量
    • 3、内部函数
    • 4、闭包
    • 5、匿名函数
    • 6、系统自带的函数
    • 7、递归函数
  • 二、文件操作
  • 三、os 模块
    • 1、os.path
    • 2、os 里边的函数
  • 四、异常
  • 五、推导式
    • 1、列表推导式
    • 2、集合推导式
    • 3、字典推导式
  • 六、生成器
  • 七、迭代器

一、函数

def 函数名():函数体

调用:函数名() —>找到函数,并执行函数体的内容
写了函数名() 就是调用,调用的过程是,系统先顺着名字找到地址,找到地址就找到了内容,之后执行内容。

1、函数的参数

定义:
def 函数名(参数):函数体调用:

求随机数的函数,产生的个数不确定:
定义的时候定义的参数:形参(占位)
调用的时候需要的参数:实参(具体的参数)

import random
def generate_random(number):for i in range(number):ran = random.randint()print(ran)
print(generate_random)
输出:>>>
<function generate_random at 0x00000238957C8AE8>
generate_random(3)
输出:>>>
7
6
5

练习 1:封装一个用户登陆函数

'''
定义一个登陆函数,参数是 uername, password
函数体:
判断参数传过来的 username、password 是否正确,如果正确则登陆成功,否则登陆失败
'''
# 函数的定义
def login(username, password):uname = 'admin123'pword = '112233'for i in range(3):if username == uname:print('登陆成功!')breakelse:print('用户名或密码不匹配,登陆失败!')username = input('请输入用户名:')password = input('请输入密码:')else:print('超过三次错误,用户锁定!')# 函数的调用
username = input('请输入用户名:')
password = input('请输入密码:')
login(username, password)
>>>
请输入用户名: admin123
请输入密码: 112233
登陆成功!

练习 2:封装一个求最大值的函数

# 定义
def max(iterable):max = iterable[0]for i in iterable:if i > max:max = iprint('最大值是:', max)
# 调用
list1 = [3,6,3,2,7]
max(list1)
>>>
最大值是: 7
# 定义
def min(iterable):min = iterable[0]for i in iterable:if i < min:min = iprint('最小值是:',min)
# 调用
list1 = [3,6,3,2,7]
min(list1)
>>>
最小值是: 2

判断是不是 list、tuple等类型:isinstance()

# isinstance(名称,类型)
print(isinstance(list1,list))
>>>
True

练习3:模拟 enumerate

s = [1,3,5,7,9]
for i in s:print(i)
print('-----------------')
for index,value in enumerate(s):print(index,value)
print('-----------------')
list1 = []
index = 0
for i in s:t1 = (index,i)list1.append(t1)index+=1
print(list1)
print('-----------------')
for index,value in list1:print(index,value)
>>>
1
3
5
7
9
-----------------
0 1
1 3
2 5
3 7
4 9
-----------------
[(0, 1), (1, 3), (2, 5), (3, 7), (4, 9)]
-----------------
0 1
1 3
2 5
3 7
4 9
# 定义
def enumerate(value):list1 = []index = 0for i in value:t1 = (index,i)list1.append(t1)index += 1for index,value in list1:print(index,value)
#调用:
value = [1,3,5,7,9]
enumerate(value)
>>>
0 1
1 3
2 5
3 7
4 9

列表是可变的,字符串是不可变的,

# 列表可变
list1 = [1,2,3,4]
list2 = list1
list1.remove(3)
print(list2)
>>>
[1, 2, 4]
# 字符串不可变
s1 = 'abc'
s2 = s1
s1 = 'abcd'
print(s2)
>>>
abc

可变参数的定义方式:

# 定义
def add(*args):print(args)
# 调用
add()
add(1,)
add(1,2)
>>>
()  # 空元组
(1,)
(1, 2)

可变参数必须放在不可变参数的后面

def add(name, *args):print(name, args)
add('aa',1,2,3)
>>>
aa (1, 2, 3)

默认值:

def add(a, b=10):result = a+bprint(result)
add(3)
add(4,7)  # b=7,会覆盖掉默认的b=10
>>>
13
11
# 想给c赋值,不想给b赋值,通过关键字赋值
def add1(a,b=10,c=4):result = a+b+cprint(result)
add1(2,c=10)
>>>
22

打印每位同学的姓名和年龄:

students={'001':('王俊凯', 20),'002':('易烊千玺',19), '003':('王源',19)}
def print_boy(person):if isinstance(person, dict):for name, age in person.values():print('{}的年龄是: {}'.format(name,age))
print_boy(students)
>>>
王俊凯的年龄是: 20
易烊千玺的年龄是: 19
王源的年龄是: 19

关键字参数:

# **kwargs:关键字参数,必须按 a=10,c=9 这样来赋值
# 得到字典形式的结果
def func(**kwargs):print(kwargs)
func(a=1,b=2,c=3)
>>>
{'a': 1, 'b': 2, 'c': 3}

能用字典传入吗?

给函数赋值的时候,传递实参的时候,用到 ** 的时候,把这个字典拆包,拆成关键字的形式。拆成 001=python, 003=java…,

dict = {'001':'python','002':'java','003':'c++','004':'go'}def func1(**kwargs):print(kwargs)
# 调用
func1(**dict)
>>>
{'001': 'python', '002': 'java', '003': 'c++', '004': 'go'}

使用的时候:
调用的时候用 **dicts:拆包, 穿实参的时候加 **,系统会先拆成关键字的形式(001=python,002=java…)
定义的时候用 **kwargs:装包,把拆完的又给装成字典

def bb(a, b, *c, **d):print(a,b,c,d)
bb(1,2)
bb(1,2,3,4)
bb(1,2,x=10,y=20)
bb(1,2,3,x=100)
>>>
1 2 () {}
1 2 (3, 4) {}
1 2 () {'x': 10, 'y': 20}
1 2 (3,) {'x': 100}

函数返回值:将函数运算的结果,利用return的形式返回来,return result。

# 把函数的输出结果扔出来
def add(a,b):result1 = a+breturn result1
result = add(1,2)
print(result)
>>>
3

练习 1:加入购物车

'''
加入购物车
判断用户是否登录,如果登录,则成功加入购物车,如果没有登陆,则提示登陆之后再添加
'''
islogin = False # 用于判断用户是否登录的变量,默认是没有登陆的
def add_shoppingcart(goodsName):global isloginif islogin:if goodsName:print('成功加入购物车!')else:print('登陆成功,没有选中任何商品!')else:answer = input('用户没有登陆,是否登陆?(y/n)')if answer == 'y':username = input('请输入用户名:')password = input('请输入密码:')islogin = login(username, password)else:print('很遗憾,不能添加任何商品!')
def login(username, password):if username == '李佳琪' and password == '123456':return Trueelse:print('用户名或密码有误,请重新输入:')return False# 调用函数,添加到购物车
username = input('请输入用户名:')
password = input('请输入密码:')
islogin = login(username, password)
add_shoppingcart('阿玛尼唇釉')
>>>请输入用户名: 离
请输入密码: ww
用户名或密码有误,请重新输入:
用户没有登陆,是否登陆?(y/n) y
请输入用户名: 李佳琪
请输入密码: 123456

验证码验证:

def generate_checkcode(n):s = '0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'code = ''for i in range(n):ran = random.randint(0,len(s)-1)code += s[ran]return code
def login():username = input('输入用户名:')password = input('请输入密码:')code = generate_checkcode(5)print('验证码是:',code)code1 = input('请输入验证码!')# 验证if code.lower() == code1.lower():if username == 'lijiaqi' and password == '123456':print('用户登陆成功!')else:print('用户名或密码有误!')else:print('验证码输入错误')
login()
>>>
输入用户名: lijiaqi
请输入密码: 123456
验证码是: Wavvv
请输入验证码! Wavvv
用户登陆成功!

2、全局变量和局部变量

局部变量:函数内部声明的变量,只能在函数体内改变
全局变量:声明在函数外侧的,所有函数都可以访问,在函数体中不能修改,如果要改,要在函数的开头加 global name,只有修改的时候,才需要加。

什么情况加 global:全局变量是不可变的(字符串、float等)但要修改的时候,需要加 global。如果全局变量是可变的,比如 list、修改的时候是不用加 global 的。

3、内部函数

在函数里边又声明一个函数,这个内部函数就是在大函数里边的。

特点:

  • 内部函数可以访问这个函数中声明的变量
  • 内部函数可以修改外部函数的可变类型的变量,比如list
  • 内部函数不能修改外部函数的不可变变量,要修改得加 nonlocal。
  • 内部函数不能修改全局变量,要修改得在内部函数里边加 global.

修改全局变量: global a
修改局部变量: nonlocal b

def func3():p = 100list1 = [3,1,2,4]# 声明内部函数def inner_func():for index in range(len(list1)):list1[index] +=5print(list1)inner_func()
func3()
>>>
[8, 6, 7, 9]
def func3():p = 100list1 = [3,1,2,4]# 声明内部函数def inner_func():for index,value in enumerate(list1):list1[index] = value + 5print(list1)inner_func()
func3()
>>>
[8, 6, 7, 9]
a = 100
print(globals())
def func():b = 90def inner_func():global anonlocal bc = 88# 尝试修改c += 12b += 10a += 10print(a, b, c)inner_func()print(locals())
func()
>>>
110 100 100
{'inner_func': <function func.<locals>.inner_func at 0x00000238961E37B8>, 'b': 100}

locals() 函数:是一个内置函数,可以查看当前函数中声明内容有哪些
locals() 输出的形式: key:values
globals() 函数:查看全局变量有哪些,以字典的形式输出。

4、闭包

闭包是在函数中提出的概念,也就是在外部函数的外部访问内部函数。

闭包的格式:在函数里边定义了一个内部函数,把内部函数通过 return 给扔出来了,就叫闭包。

闭包的条件:

  • 必须要有内部函数
  • 内部函数必须引用外部函数的变量
  • 外部函数是有返回值的,返回的值是内部函数名

格式:

def 外部函数():...def 内部函数():...return 内部函数名
def func():a = 100def inner_func():b = 90print(a,b)return inner_func
# 调用,相当于把 inner_func 给了a,a就是内部函数了,然后调用该内部函数,就给 a 加括号就好啦
a = func()
a()
>>>
100 90
def func(a,b):c = 10def inner_func():s = a+b+cprint('相加之和的结果是:', s)return inner_func
ifunc = func(6,9)
ifunc()
ifunc = func(5,6)
ifunc()
>>>
相加之和的结果是: 25
相加之和的结果是: 21

闭包的特点:

  • 能够保存返回闭包时的状态,不会受后面输入参数变化的影响。

5、匿名函数

简化函数的定义

定义格式:lambda 参数1,参数2 : 运算

有lambda,底层就会给你创建一个函数,这个函数是没有名字的,匿名的,前面是参数,:后面的就相当于 return 返回的结果。

# s 是一个函数
s = lambda a,b : a+b
result = s(1,2)
print(result)
>>>
3

匿名函数可以作为参数:

def func(x, y, func):print(x, y)print(func)s = func(x, y)print(s)
func(1, 2, lambda a, b : a + b)
>>>
1 2
<function <lambda> at 0x0000023896096378>
3
list1 = [3,4,5,6,8]
m = max(list1)
print('列表最大值:',m)
list2 = [{'a':10,'b':20},{'a':13,'b':20},{'a':9,'b':20},{'a':29,'b':20}]
# 找 a 的最大值
m = max(list2, key = lambda x:x['a'])
print('列表的最大值:',m)
>>>
列表最大值: 8
列表的最大值: {'a': 29, 'b': 20}

6、系统自带的函数

1、map() 函数,对列表中元素进行操作,免去了之前的for循环

# map(操作函数,操作对象)
map(lambda ..., list1)
list1 = [3,4,5,6,7,9]
result1 = map(lambda x : x+2, list1)
print(list(result1))
>>>
[5, 6, 7, 8, 9, 11]

如果是偶数,则返回偶数本身,如果不是偶数,则进行+1操作:

# 方法一
func = lambda x : x if x%2 == 0 else x+1
result = func(5)
print(result)
>>>
6
# 方法二,对列表中的奇数进行+1,偶数不变
result = map(lambda x : x if x%2 == 0 else x+1, list1)
print(list(result))
>>>
[4, 4, 6, 6, 8, 10]

2、reduce() 函数,对列表(可迭代的)中的元素进行 ±*/

from functools import reduce
tuple1 = (3,5,6,7,8)
result = reduce(lambda x, y: x+y, tuple1)
print(result)
>>>
29

3、filter() 函数,过滤符合条件的元素,且原始的list不会被改变

list1 = [3,4,5,6,8]
result = filter(lambda x:x>5, list1)
print(list(result))
>>>
[6, 8]
students = [{'name':'lucy','age':21},{'name':'tomy','age':20},{'name':'jack','age':19},{'name':'json','age':18},]
result = filter(lambda x:x['age']>20,students)
print(list(result))
>>>
[{'name': 'lucy', 'age': 21}]

按照年龄从小到大排序:

result = sorted(students, key=lambda x:x['age'])
print(result)
>>>
[{'name': 'json', 'age': 18}, {'name': 'jack', 'age': 19}, {'name': 'tomy', 'age': 20}, {'name': 'lucy', 'age': 21}]

总结:
max(), min(), sorted():都可以结合key来选择
map():将列表中的每个元素进行统一操作
reduce(): 对列表中的元素进行累加啊
filter():过滤

7、递归函数

普通函数:def func(): pass
匿名函数: lambda 参数:返回结果
递归函数:普通函数的一种表现形式,函数自己调用自己

递归函数的特点:

  • 一定要有终点(加判断)
  • 通常都会有一个入口
def sum(n):if n == 0:return 0else:return n+sum(n-1)
sum(10)
>>>
55

二、文件操作

1、mode:

  • r : read 读,纯文本文件
  • w: write 写,纯文本文件
  • rb:read binary 二进制读,包括纯文本、图片、音乐、MV等
  • wb:write binary 二进制写
  • a: append 追加

这里的读写,其实就是确定管道的类型:读、写

系统函数:

open(file, mode, buffering...)

open 就相当于给 file.txt 和 pycharm 建立了一个管道,.read() 就相当于把文件中的东西给读出来,通过管道传递出来。

2、读

stream = open(filename, 'r')
# 返回值是一个stream,流管道
# 然后用 read 去读
container = stream.read()
stream = open(r'file.txt')
# .read() 读所有内容
container = stream .read()
print(container)
# .readable() 判断是否可以读取
container = stream.readable()
print(container)
>>>
hello world!
hello kitty!
hello May!
-----------------------
True
-----------------------
stream = open(r'file.txt')
# .readline() 一行一行读
line = stream.readline()
print(line)
>>>
hello world!

readline() 通常用 for 循环

stream = open(r'file.txt')
while True:line = stream.readline()print(line)if not line:break
>>>
hello world!hello kitty!hello May!
# .readlines(),全部读取,保存在列表里
stream = open(r'file.txt')
lines = stream.readlines()
print(lines)
print('---------------------------')
for i in lines:print(i)
>>>
['hello world!\n', 'hello kitty!\n', 'hello May!']
---------------------------
hello world!hello kitty!hello May!

读取图片,要使用 rb 方式

stream = open(r’image.jpg’,‘rb’)
container = stream.read()

3、写

  • stream.write('内容‘)
  • stream.writelines(Iterable),没有换行的效果,可以自己加\n

特点:

  • 在对 stream 的操作时,都会把原来的内容覆盖掉。也就是上次写的内容覆盖掉,但不会把这一次读写的内容覆盖掉。

从得到一个 stream 到关闭这个 stream 叫一次读/写,这一次的读/写中,可以多次对这个 stream 进行操作。

stream = open('file.txt','w')
s = 'hello xiao ming!'
stream.write(s)
stream.write('hello xiao hua!')
stream.close()

换行写:

stream = open('file.txt','w')
stream.write('hello jenny!')
stream.writelines(['hello denny!\n','hello xiao hong!\n'])


4、追加模式 a

在写的时候,不会把之前的内容擦掉,会在后面追加

stream = open('file.txt','a')
stream.write('hello jenny!\n')
stream.writelines(['hello denny!\n','hello xiao hong!\n'])


5、文件的复制

原文件:\img\image.jpg
目标文件:\img\image1.jpg

每次要打开,要关闭 stream 会比较麻烦,可以直接用 with,with可以帮助我们自动释放资源。

with open('image.jpg','rb') as stream:container = stream.read()with open('image1.jpg','wb') as wstream:wstream.write(container)
print('文件复制完成!')
>>>
文件复制完成!

三、os 模块

operation system

模块的概念:.py就是一个模块

stream.name 可以得到文件的路径+名称

os.path:

  • os.path.dirname(‘file’) :获取当前文件所在的文件目录(绝对路径)
  • os.path.join(path,‘img.jpg’):返回一个拼接后的新路径
# 1、绝对路径
os.path.dirname()
with open('image.jpg','rb') as stream:container = stream.read()path = os.path.dirname('__file__')path1 = os.path.join(path,'image2.jpg')with open(path1,'wb') as wstream:wstream.write(container)
print('文件复制完成!')
with open('p1/image1.jpg','rb') as stream:container = stream.read()print(stream.name)file = stream.namefilename = file[file.rfind('/')+1:] # 截取文件名path = os.path.dirname('__file__')path1 = os.path.join(path, filename)with open(path1,'wb') as wstream:wstream.write(container)
print('文件复制完成!')
>>>
p1/image1.jpg
文件复制完成!

1、os.path

os.path

  • absolute:绝对路径
  • 表示当前文件的上一级,…/
import os
# 1、判断是否是绝对路径
os.path.isabs(r'p1/image.jpg')
>>>
False

获取文件所在文件夹的当前路径:

path = os.path.dirname('__file__')
print(path)
>>>
C:\Users\man.wang\python\python\part4.py

获取绝对路径:

path = os.path.abspath('file.txt')
print(path)
>>>
C:\Users\man.wang\python\python\file.txt

获取当前文件的绝对路径:

path = os.path.abspath('__file__')
print(path)

获取当前文件的文件夹所在的路径:

path = os.getcwd()  #
print(path)
>>>
C:\Users\man.wang\python\python

文件名切分:split

  • os.path.split(path):把文件名前的路径和文件名分别存成元组的两个元素
  • os.path.splitext():文件和扩展名分开,存放成元组的两个元素
# os.path.split()
path = r'C:\Users\man.wang\python\python\file.txt'
result = os.path.split(path)
print(result)
print(result[1])
>>>
('C:\\Users\\man.wang\\python\\python', 'file.txt')
file.txt
# os.path.splitext()
path = r'C:\Users\man.wang\python\python\file.txt'
result = os.path.splitext(path)
print(result)
>>>
('C:\\Users\\man.wang\\python\\python\\file', '.txt')

得到文件的大小,单位是字节个数:

  • os.path.getsize(path)
path = r'C:\Users\man.wang\python\python\file.txt'
result = os.path.getsize(path)
print(result)
>>>
92

2、os 里边的函数

获取当前文件所在的目录:os.getcwd()

result = os.getcwd()
print(result)
>>>
C:\Users\man.wang\python\python

获取文件夹中的所有文件/文件夹的名字:os.listdir()

path = r'C:\Users\man.wang\python\python'
result = os.listdir(path)
print(result)
>>>
['.ipynb_checkpoints', 'file.txt', 'image.jpg', 'image1.jpg', 'image2.jpg', 'p1', 'p2', 'part 1.ipynb', 'part2.ipynb', 'part3.ipynb', 'part4.ipynb']

创建文件夹:os.mkdir(),如果存在则报错

所以用 os.mkdir() 时候,最好先判断文件夹是否存在

dirc = 'p3'
if not os.path.exists(dirc):os.mkdir('p3')

删除空文件夹:os.rmdir()

os.rmdir('p3')

删除非空文件夹:要一层一层的删 os.removedirs('p3)

删除文件:os.remove()

os.remove(r'C:\Users\man.wang\python\python\p1\image.jpg')
# 删除 p1 文件夹中的所有文件
path = r'C:\Users\man.wang\python\python\p1'
filelist = os.listdir(path)
for file in filelist:path1 = os.path.join(path,file)os.remove(path1)
# 删除p1
else:os.rmdir(path)print('删除成功')
>>>
删除成功

切换目录:os.chdir()

# 切换目录,可以切换到指定目录下
f = os.chdir(r'C:\Users\man.wang\python\python\p2')
print(os.getcwd())
>>>
C:\Users\man.wang\python\python\p2

四、异常

语法没报错,运行的时候报错

def chu(a,b):return a/b
chu(1,0)
>>>
ZeroDivisionError: division by zero

异常处理:

try:可能出现异常的代码
except:如果有异常,则执行此处的代码
finally:无论是否存在异常,都会被执行的代码

如果不加异常,这段代码有问题的话,下面的所有的代码都不会被执行。

def func():try:n1 = int(input('输入第一个数字:'))n2 = int(input('输入第二个数字:'))# 加法result = n1 + n2print('两数之和为:',result)except:print('必须输入数字!')
func()
>>>
输入第一个数字: 2
输入第二个数字: w
必须输入数字!
def func():try:n1 = int(input('输入第一个数字:'))n2 = int(input('输入第二个数字:'))oper = input('请输入运算符号:(+-*/)')result = 0if oper == '+':result = n1 + n2elif oper == '-':result = n1 - n2elif oper == '*':result = n1 * n2elif oper == '/':result = n1 / n2else:print('符号输出错误!')print('结果为:',result)except ZeroDivisionError:print('除数不能为 0!')except ValueError:print('必须输入数字!')
func()
>>>
输入第一个数字: 1
输入第二个数字: 0
请输入运算符号:(+-*/) /
除数不能为 0!

如果用了 else,在 try 代码中不能出现 return,如果走了 try,然后直接就终止代码了。

情况1:

try:pass
except:pass

情况2:打印错误原因

try:pass
except Exception as err:print(err)

情况3:没有异常的时候,会执行的 else 的代码,但 try 里边不能用 return,因为没有异常的时候,

try:pass
except ValueError:pass
else:print('')

异常抛出:

# 实现用户名小于6位时抛出异常
def register():username=input('请输入用户名:')if len(username)<6:raise Exception('用户名长度必须6位以上!')else:print('输入的用户名是:',username)
register()
>>>
input-> www
Exception: 用户名长度必须6位以上!

五、推导式

从旧的列表推导得到一个新的列表

1、列表推导式

格式:

  • [表达式 for 变量 in 旧列表]
  • [表达式 for 变量 in 旧列表 if 条件]

符合 if 条件的变量,扔到最前面的表达式中

# 过滤掉长度 <= 3 的人名
names = ['tom','lily','jack','json','bob']
# 第一个 name 就放的是names中符合长度 >3 条件的 name
result = [name for name in names if len(name)>3]
print(result)result = [name.capitalize() for name in names if len(name)>3]
print(result)result = [name.title() for name in names if len(name)>3]
print(result)
>>>
['lily', 'jack', 'json']
['Lily', 'Jack', 'Json']
['Lily', 'Jack', 'Json']
# 列表推导式等价实现
names = ['tom','lily','jack','json','bob']
new_name=[]
def func(names):for name in names:if len(name)>3:name = name.title()new_name.append(name)return new_name
func(names)
>>>
['Lily', 'Jack', 'Json']
# 将 1~100 之间,能被 3 整除的扔出来
newlist = [i for i in range(1,101) if i%3 == 0]
print(newlist)
>>>
[3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]
# 将 1~100 之间,能被 3 整除,并且能被5整除的拿出来放到一个列表
newlist = [i for i in range(1,101) if i%3 == 0 and i%5 == 0]
print(newlist)
>>>
[15, 30, 45, 60, 75, 90]
# 求 0~5 之间的偶数,和 0~5 之间的奇数,构成一个元组,放到列表里边
def func():new_list=[]for i in range(5):if i%2 == 0:for j in range(5):if j%2 != 0:new_list.append((i,j))return new_list
func()
>>>
[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]
# 列表推导式写
# 在for后面再写for,就相当于循环中的嵌套
new_list = [(x,y) for x in range(5) if x%2==0 for y in range(5) if y%2 != 0]
print(new_list)
>>>
[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]

练习:不带条件的列表推导式,直接取就好啦

'''
list1 = [[1,2,3],[4,5,6],[7,8,9]] -----> list2=[3,6,9]
'''
list1 = [[1,2,3],[4,5,6],[7,8,9]]
new_list = [i[-1] for i in list1]
print(new_list)
>>>
[3, 6, 9]

练习:带 else 的列表推导式,把 for 放到最后

dict1={'name':'tom','salary':5000}
dict2={'name':'lili','salary':8000}
dict3={'name':'jack','salary':3000}
list1 = [dict1, dict2, dict3]
# 如果薪资 > 5000 加工资 200,低于等于 5000 加工资 500
new_list = [person['salary']+200 if person['salary']>5000 else person['salary']+500 for person in list1 ]
print(new_list)
>>>
[5500, 8200, 3500]

2、集合推导式

# 遍历 list 里边的元素,把元素放到集合里边,相当于去重
list1 = [1,2,3,4,5,6,3,1,2,3]
set1 = {x for x in list1}
print(set1)set2 = {x+1 for x in list1 if x>3}
print(set2)
>>>
{1, 2, 3, 4, 5, 6}
{5, 6, 7}

3、字典推导式

# key 和 value 进行交换
dict1 = {'a':'A','b':'B','c':'C','d':'C'}
new_dict = {value:key for key,value in dict1.items()}
print(new_dict)
>>>
{'A': 'a', 'B': 'b', 'C': 'd'}

六、生成器

通过列表生成式(列表推导式),可以直接创建一个列表,但是,收到内存的限制,列表容量肯定是有限的,而且,创建一个包含100w个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面的大多数元素占用的空间就白白浪费了。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算后续的元素呢,这样就不必创建整个list了,从而能够大量的节省空间,在 python 中,这种一边循环,一边计算的机制,成为生成器(generator)。

得到生成器的方式:

  • 通过列表推导式得到生成器(用小括号)
# [0,3,6,9,12,15,18,21,24,27]
# 1、列表推导式
new_list = [x*3 for x in range(20)]
print(new_list)
>>>
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57]
# 2、列表生成式,只要调一下,就产生一次
# 得到生成器
g = (x*3 for x in range(20))
print(type(g))
print(g)
# 方式一
print(g.__next__())
print(g.__next__())
print(g.__next__())
>>>
<class 'generator'>
<generator object <genexpr> at 0x000002BFF85C4F48>
0
3
6# 方式二:next(),每调用一次,就会产生一个元素
print(next(g))
print(next(g))
print(next(g))
>>>
9
12
15# 生成器产生元素完毕,你再次调用的时候,就会报错
print(next(g))
>>>
StopIteration:

使用一个循环来搞定:

g = (x*3 for x in range(10))
while True:try:e = next(g)print(e)except:print('没有更多元素啦!')break
>>>
0
3
6
9
12
15
18
21
24
27
没有更多元素啦!

yield():函数里边有yield,说明函数就不是函数了,就变成了生成器

'''
使用函数得到生成器:1、定义一个函数,函数中使用yield2、调用函数,并接收调用的结果3、得到生成器4、借助 next()/__next()__ 得到元素
'''
# 调用 func() 的时候是不会走到函数里边去的
# 只有用 next() 的时候才会走到函数里边
def func():n = 0while True:n += 1yield n  # return+暂停
g = func()
>>>
<generator object func at 0x000002BFF923EC78>
# yield 就相当于 return + 暂停,把 n 扔出去,并且停下来,不进行循环了,当你下次再用 next() 的时候,值再走到 while true里边,进行下一次循环。
def func():n = 0while True:n += 1yield n
g = func()
print(next(g))
print(next(g))
print(next(g))
print(next(g))
>>>
1
2
3
4

斐波那契数列:

def fib(length):a, b = 0, 1n = 0while n<length:
#         print(b)yield ba, b = b, a+bn += 1return '没有更多元素!'
g = fib(8)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
>>>
1
1
2
3
5
8
13
21
StopIteration: 没有更多元素!

生成器方法:

  • next():获取下一个元素
  • send():像每次生成器中传值的,第一次调用的时候必须先传一个 None

生成器应用:

进程>线程>协程

一个进程可以用多个线程来并行完成,一个线程又可以用多个协程来并完成。

# 任务是前后进行的,先搬完砖才能听歌
def task1(n):for i in range(n):print('正在搬第{}块转'.format(n))def task2(n):for i in range(n):print('正在听第{}首歌'.format(n))
task1(3)
task2(3)
>>>
正在搬第0块转
正在搬第1块转
正在搬第2块转
正在听第0首歌
正在听第1首歌
正在听第2首歌
# 两个任务同时进行
def task1(n):for i in range(n):print('正在搬第{}块转'.format(i))yield None
def task2(n):for i in range(n):print('正在听第{}首歌'.format(i))yield None
g1 = task1(3)
g2 = task2(3)
while True:try:g1.__next__()g2.__next__()except:break
>>>正在搬第0块转
正在听第0首歌
正在搬第1块转
正在听第1首歌
正在搬第2块转
正在听第2首歌

生成器的构成:

  • 通过列表推导式完成
  • 通过 函数 + yield 完成

产生元素:

  • next(generator)
  • 生成器自己的方法
    • generator._ next _(),产生完毕再次调用,会产生异常
    • generator.send(),给生成器送值

生成器的应用:在协程中使用

七、迭代器

可迭代的对象:

  • 生成器
  • 元组、列表、集合、字典、字符串

如何判断是否可迭代:isinstance()

from collections import Iterable
# 列表是可迭代的
list1 = [1,2,3]
isinstance(list1,Iterable)
>>>
True
# 整型是不可迭代的
isinstance(1,Iterable)
>>>
False
# 生成器是可迭代的
g = (x +1 for x in range(10))
isinstance(g,Iterable)
>>>
True

迭代器:可以被 next() 函数调用并不断返回下一个值的对象,称为迭代器 iterator

  • 迭代器是访问集合元素的一种方式
  • 迭代器是可以记住遍历位置的对象,迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问结束
  • 迭代器只能往前,不能后退

生成器:可迭代,也是迭代器(可以用 next() 方法)
列表:可迭代,但不是迭代器(不可以 next() 方法)

怎么把一个可迭代的对象变成迭代器:iter(obj)

list1 = [1,2,3]
print(type(list1))
list1 = iter(list1)
print(type(list1))
print(next(list1))
print(next(list1))
>>>
<class 'list'>
<class 'list_iterator'>
1
2

生成器:为了节省内存,一个个拿到元素,生成的方式有两种,一种是 列表生成式的方式,另一种是借助函数+yield方式。
迭代器:只要能够调用 next得到下一个元素的,就叫迭代器

迭代器是一个大的范围, 生成器是迭代器的一种,生成器也是迭代器。

列表/元组等不是一个迭代器,但也可以变成一个迭代器。

迭代器:

  • 借助 iter() 转换,可以得到
  • 不借助,本身就是迭代器

【python 2】python 进阶相关推荐

  1. Python之面向对象进阶

    Python之面向对象进阶 进阶有:Python 类的成员.成员修饰符.类的特殊成员. 一.类的成员 类的成员可以分为三大类:字段.方法和属性. 注:所有成员中,只有普通字段的内容保存对象中,即:根据 ...

  2. 怎么更进一步学python_【百尺竿头,更进一步学Python】Python进阶课程——进程,线程和协程的区别...

    本文带来各类奇怪的IT百科知识. [百尺竿头,更进一步学Python]Python进阶课程--进程:线程和协程的区别 现在多进程多线程已经是老生常谈了:协程也在最近几年流行起来.今天我们本文主要介绍进 ...

  3. Python工程能力进阶、数学基础、经典机器学习模型实战、深度学习理论基础和模型调优技巧……胜任机器学习工程师岗位需要学习什么?...

    咱不敢谈人工智能时代咋样咋样之类的空话,就我自己来看,只要是个营收超过 5 亿的互联网公司,基本都需要具备机器学习的能力.因为大部分公司盈利模式基本都会围绕搜索.推荐和广告而去. 就比如极客时间,他的 ...

  4. python函数-函数进阶

    python函数-函数进阶 一.命名空间和作用域 1.命名空间 内置命名空间 -- python解释器 就是python解释器一启动就可以使用的名字存储在内置命名空间中 内置的名字在启动解释器的时候被 ...

  5. python的格式化输出学号_安利三个关于Python字符串格式化进阶知识

    点击蓝色"Python空间"关注我丫 加个"星标",每天一起快乐的学习 今 日 鸡 汤 名花倾国两相欢,常得君王带笑看. /前言/ 关于Python字符串格式化 ...

  6. [转载] Python Web开发—进阶提升 490集超强Python视频教程 真正零基础学习Python视频教程

    参考链接: 在Python中创建代理Web服务器 2 Python Web开发-进阶提升 490集超强Python视频教程 真正零基础学习Python视频教程 [课程简介] 这是一门Python We ...

  7. 学会python爬虫能发财么_python如何赚钱? python爬虫如何进阶? python就业? 如何快速入门python?...

    1.如何快速入门 Python ? 我之前给大家说过,速成一门技能是不可能的,你需要花很多时间才能真正的掌握一门技能,但是快速入门是有可能的,而且也是必要的,你需要掌握最少且最必要的知识点,先进门再说 ...

  8. python 变量使用进阶

    python 变量使用进阶 文章目录 python 变量使用进阶 什么是变量的作用域? 作用域的产生 作用域的类型 **变量名解析LEGB法则** global与nonlocal关键字 python针 ...

  9. Python小白的进阶之路---Day5

    Python小白的进阶之路---Day5 1.file 1.1打开文件方式(读写两种方式) 1.2文件对象的操作方法 1.3学习对excel及csv文件进行操作 2.os模块 3.datatime模块 ...

  10. python高级练习题:多米诺平铺 - 5×2N局【难度:4级】--景越Python编程实例训练营,不同难度Python习题,适合自学Python的新手进阶

    python高级练习题:多米诺平铺 - 5×2N局[难度:4级]: 请还检查了在[多米诺拼接系列]其他练习题(https://www.codewars.com/collections/5d19554d ...

最新文章

  1. java 项目加载dll文件,在eclipse java项目中加载dll文件
  2. nodejs实现的简单接口
  3. 初看jQuery,比较dojo与jQuery的不同点
  4. 第一次用51的博客,记录一下笔记
  5. JavaScript HTML DOM
  6. 前世档案 (15 分)
  7. arcgis desktop 10.1 license manager无法启动问题解决
  8. 李开复、张亚勤、吴恩达…国际大咖给你讲解AI知识
  9. 服务器 python cant open file_如何删除分析*。gcda:无法打开python virtualenv builder出错?...
  10. windows 进程学习
  11. Ubuntu安装腾达u12驱动
  12. 适合于图像处理方向的SCI期刊杂志列表【部分转载】
  13. python 阮一峰_ES6 Iterator笔记(摘抄至阮一峰的ECMAScript 6入门)
  14. opencv学习笔记之像素处理
  15. 2021-01-22 Science对于“Misused images”图片误用的报道
  16. pandas, dataframe获取最后一行的三种方法
  17. sql 累计占比_sql中查询占百分比percent和通配符的使用
  18. style-loader 与css-loader 处理 css样式文件
  19. 12.20-12.21北大医药
  20. oracle数据库注入实战,教你oracle注入

热门文章

  1. 网络安全-安全散列函数,信息摘要SHA-1,MD5原理
  2. 来自东软的 OpenStack 负载均衡即服务开源项目
  3. 【Java每日一题】20161219
  4. nginx日志中文变成类型\xE9\xA6\x96\xE9\xA1\xB5-\xE6\x8E\xA8\xE8\x8D\x90的东西
  5. Swift 数组、字典
  6. 设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释
  7. linux的mount(挂载)命令详解(转)
  8. mysql 命令 pdf_MySQL命令文档 PDF 下载
  9. 人工智能状态图matlab,人工智能—TensorFlow(七):matplotlib图形可视化
  10. c语言中指,浅析C语言中指与数组.doc