lingview
lingview
发布于 2025-01-28 / 87 阅读
0
0

记录python的一些笔记

python基础部分:

一:计算机基础及python运算符:

1.1编码:

  • ASCII编码:只能表示英文字符,数字及特殊的英文字符。用1个字节表示。
  • Unicode编码:能表示世界上所有的字符,用4个字节表示。
  • UTF-8编码:Unicode的压缩版,能表示世界上所有的字符,用1~4个字节表示,中文占3个字节。
  • GBK编码:国标码,中文占2个字节。

1.2python2和python3的区别:

python2python3注备
str不同有unicode类型 v = u'李杰'  str类型 v='李杰'有str类型  byte类型  v = b'李杰'py2中的str等价于py3中的byte,py2的unicode类型等价于py3的str类型
编译器编码ASCIIUTF-8# _ * _ coding:utf-8 _ * _ 可以指定编译器的编码
整数int具有范围,超出后自动转换成long无范围
两个整数相除只保留整数部分保留全部from future import division可解决python2中2个整数相除只保留整数部分
输入raw_input()input()
输出print 关键字print() 函数
随机数xrange() 生成一个可迭代对象 range() 生成的是一个列表range()直接生成一个可迭代对象
文件和包包里面必须有__init__.py可有可无
字典items,keys,values map/filter直接生成列表返回迭代器

1.3python运算符的优先级

运算符概述
**指数(最高优先级)
~、+、-按位翻转,一元加号和减号(最后两个的方法名为+@-@
*、/、%、//乘、除、取模和取整除
+、-加法、减法
>>、<<右移、左移运算符
&位与
^、|位运算符
<=、<、>、>=比较运算符
<> == !=等于运算符
= %= /= //= -= += *= **=赋值运算符
is is not身份运算符
in in not成员运算符
not or and逻辑运算符

二:数据类型:

2.1.1整形(int)

在python2中:

  • 在32位机器上,整数的位数为32位,取值范围为-2* * 31~2 * * 31-1
  • 在64位机器上,整数的位数为64位,取值范围为-2* * 63~2 * * 63-1
  • 超出范围之后自动转换为long

在python3中:

  • 只有int类型,没有long

注意:在ptrhon2中2个整数相除只会保留整数位,如果想要保留全部需要导入模块:form __ future __ import divsision

2.1.2布尔值(bool)

true或者false
以下值会被解释为false:

  • 0,'',{},(,),[],set(),None

2.1.3.字符串(str)

独有功能:

  • 大小写转换:upper()/lower
  • 判断是否可以转换为数字:isdecimal()
  • 去两端空格:strip()
  • 替换:replace()
  • 分割:split()
  • 判断开头和结尾:startswith()/endswith()
  • 连接:join()
  • 格式化:format()
  • 编码:encode()
  • 查找:find()/index()

​ 区别:find()找不到返回-1,index()找不到会报错

通用功能:

  • len/索引/切片/步长/for循环

2.1.4.列表:

独有功能:

  • 添加:

    append(元素) 在末尾追加元素

    insert(索引值,元素) 在指定位置添加

    extent() 追加用于for循环的每一个元素

  • 删除:

    remove(元素) 删除指定元素

    pop(索引值) 删除指定位置的元素,不写索引值默认删除最后一个

    clear() 清空列表中的所有元素

  • 查找:

    reverse() 翻转列表中的元素

  • 排序:

    sort(reverse=True/False) 从大到小/从小到大排序,默认False

通用功能:

  • len/索引/切片/步长/for循环/删除/更新 

列表表达式:

  • [变量名 for 变量名 in 可迭代对象 条件 ]
print([i for i in range(10)])
#结果:[0,1,2,3,4,5,6,7,8,9]

print([i for i in range(10) if i > 5])
#结果:[6,7,8,9]

2.1.5.元祖:

独有功能:

通用功能:

  • len/索引/切片/步长/for循环 

2.1.6.字典

独有功能:

  • 获取键,值,键值对 keys()/values()/items()
  • 获取值 get()
  • 删除键值对 pop(key)
  • 增加键值对 update()

通用功能:

  • len/索引/for循环/修改/删除

2.1.7.集合

独有功能:

  • 增加

    add()

    update()

  • 删除 discard()

  • 交并差:instersection()/union()/difference()

通用功能:

  • len/for循环

2.2.可变类型和不可变类型:

  • 可变类型:列表,字典,集合
  • 不可变类型:数字,字符串,元祖,布尔值

2.3.深浅拷贝

  • 深拷贝:

    拷贝嵌套层次中的所有可变类型
    在一些赋值操作中可能会用到这个时候就要导入copy库使用copy.deepcopy进行深拷贝

  • 浅拷贝:

    只能拷贝第一层的内容

2.4.is 和 == 的区别:

  • is是判断内存是否相等
  • == 是判断值是否相等

三:文件操作

大文件的内容读取:

#方法1:
str = ""
with open("data.txt", mode="r", encoding="utf-8") as f:
	for data in f:
		str += data  # 按行读取

#方法2:
str = ""
with open("data.txt", mode="r", encoding="utf-8") as f:
    while True:
        data = f.readline()
        if data != "":
            str += data
        else:
            break
print(str)

移动光标:seek()

  • 移动到开头seek(0,0)
  • 移动到结尾seek(0,2)) seek的第二个参数表示的是从哪个位置进行偏移,默认是0,表示开头,1表示当前位置,2表示结尾
  • seek(6)如果是单数而且不是0是按照字节来移动

获取光标的位置:tell()

四:函数相关

函数的默认返回值为None

函数式编程:增加代码的可读性和重用性

4.1传参的分类:

  • (1)位置传参:只能参数一一对应
  • (2)关键字传参:关键字参数只能放在位置传参的后面.
  • (3)默认参数传参:可以接受参数,不传参数将使用默认值,
    • 注意:默认关键字如果是不可变类型,可以随便玩,如果是可变类型,需要注意有一个坑.
    • 如果默认参数设置成可变类型为空,改可变类型会创建在函数中,不会被释放,因此在下次调用时还会继续使用上次一创建的可变类型中的数据.
def func(data, value=[]):  # 不推荐 
    value.append(data)
    return value


print(func(11))  # [11]
print(func(1, [11, 22, 33]))  # [11,22,33,1]
print(func(22))  # [11,22]


def fun1(data, value=None):  # 推荐
    if not value:
        value = []
    value.append(data)
    return value

print(fun1(11))  # [11]
print(fun1(1, [11, 22, 33]))  # [11,22,33,1]
print(fun1(22))  # [22]

  • (4)万能传参:可以接受n个参数
# 实例1: *args 只能接受位置传参
def fun1(*args):
    print(args)

fun1((11, 22, 33, 44)) # 结果: ((11, 22, 33, 44))
fun1(*(11, 22, 33, 44)) # 结果: (11, 22, 33, 44)

# 实例2: **kwargs 只能接受关键字传参
def fun2(**kwargs): # 添加冒号
    print(kwargs)

fun2(k1=11, k2=22) # 结果: {'k1': 11, 'k2': 22}
fun2(k1=11, **{'k2': 22, 'k3': 33}) # 结果: {'k1': 11, 'k2': 22, 'k3': 33}

4.2函数的作用域

  • 一个函数就是一个作用域.
  • 作用于查找数据的规则:优先在自己的作用域中查找数据,自己没有就去上一级去找,
  • 子作用域只能找到父级中的值,默认无法重写赋值
# 全局变量 a 是一个列表

  

a = [11, 22]

def fun():
	global a # 声明 a 是全局变量
	a.append(33) # 修改全局变量 a

  

fun()

print(a) # 结果: [11, 22, 33]

  

# 全局变量 a 是一个字符串

a = "aaa"

  

def fun1():

# 这里不声明全局变量
	a = "bbb" # 修改全局变量 a

fun1()

print(a) # 结果: "aaa"
  • 如果非要修改上一级或者全局变量需要添加关键字global或者nonlocal关键字

  • 如果非要去修改则可以使用global 或 nonlocal关键字

    globla:直接声明为全局变量

    nonlocal:声明为上一级变量,不一定是全局变量大

  • 全局变量的命名采用全部大写,局部变量采用小写

4.3函数小高级

4.3.1函数可以赋值

def func():
    print(123)

list = [func,func,func]  # func为函数的地址
for i in list:
    i()  # 运行函数

4.3.2函数做参数

def fun(arg):

    arg()

def show():

    print(111)

fun(show) # 输出111

4.3.3函数做字典的值

#应用:
def fun1():
    print("fun1")
def fun2():
    print("fun2")  
def fun3():
    print("fun3")
def fun4():
    print("fun4")
def fun5():
    print("fun5")
    
fun_dict ={"f1":fun1,"f2":fun2,"f3":fun3,"f4":fun4,"f5":fun5,}
chooice = input("请选择功能:")
find_fun = fun_dict.get(chooice)
if find_fun:
    find_fun()
else:
    print("请检查输入内容后在重新运行!")
    

4.4lambda表达式及三元运算符

4.4.1三元运算符:

  • 为了解决简单的if else情况
# 定义变量 a 和 b
a = 10
b = 20

# 普通写法:
max_value = None
if a > b:
    max_value = a
else:
    max_value = b

print(f"较大的数是: {max_value}")

# 三元运算符写法
max_value = a if a > b else b

print(f"较大的数是: {max_value}")

4.4.2lambda表达式:为了解决简单的函数

def func(a, b):
    return a + b

result = func(3, 5)
print("普通函数结果:", result)

func = lambda a, b: a + b

result = func(3, 5)
print("lambda表达式结果:", result)

4.5内置函数:

  • 数据类型转换相关:

    • int 转换为整形

    • float 转换为浮点型

    • bool 转换为布尔型

    • chr 转换为字符型

    • ord 将一个unicode编码中的一个字符转换成10进制数

#实例:验证码生成器
import random
    
    
def get_yzm(longth=6):
    yzm = []
    for x in range(6):
        v = random.randint(65,90)
        yzm.append(chr(v))
    return "".join(yzm)
    
    
print(get_yzm())
  • str 转换为字符串类型

  • list 转换为列表

  • dict 转换为字典

  • tuple 转换为元祖

  • set 转换为集合

  • 数学相关:

    • abs 取绝对值

    • max 取最大值

    • min 取最小值

    • sum 求和

    • divmod 求商和余数

# 实例:分页
def show_pige(data, pige_num, show_num=10):
    pige, a = divmod(len(data),show_num)
    max_page =pige + 1 if a > 0 else pige
    if pige_num < 0 or pige_num > max_page:
        print("输入的值超出范围0~%s" %max_page)
    else:
        start_pige_num = show_num*(pige_num - 1)
        end_pige_num = start_pige_num + show_num
        for i in range(start_pige_num,end_pige_num+1):
            print(data[i])
    
if __name__ == '__main__':
    list = []
    for i in range(0, 856):
        list.append("data%s" %i)
    pige_num = int(input("请输入要查看的页数:"))
    show_pige(list, pige_num, 20)
    
  • 进制转换:

    • bin 将10进制转换为2进制
    • oct 将10进制转换为8进制
    • int 将其他进制转换为10进制
    • hex 将10进制转换为16进制
#1十进制转换二,八,十六进制
num = 100

print(bin(num))
print(oct(num))
print(hex(num))

#2 其他进制转换成10进制
num_0b = "0b1100100"
num_0o = "0o144"
num_0x = "64"

print(int(num_0b,base=2))
print(int(num_0o,base=8))
print(int(num_0x,base=16))
  • 其他:map/filter/reduce第一个参数必须是一个函数,第二个参数是一个可以迭代的类型

    • map() 遍历序列,对序列中每个元素进行操作,最终获取新的序列。

Pasted image 20250112141029.png

#1.map函数应用:

#需求:每个元素增加100

li = [11,22,33,44,55,66,77,88,99]

new_list = map(lambda x:x+100, li)

print(list(new_list))
  • filter() 对于序列中的元素进行筛选,最终获取符合条件的序列

Pasted image 20250112141629.png

#2.获取列表中大于12的所有元素集合

li = [10, 15, 20, 25]

new_set = filter(lambda x : x > 12 ,li)

print(list(new_set))
  • reduce() 对序列内的所有元素进行累计操作

Pasted image 20250112141855.png

#3.获取列表中所有元素的和

import functools

  

li = [1, 2, 3, 4, 5]  

new_list = functools.reduce(lambda x, y : x+y, li)

print(new_list)
  • 面试题:ip地址转换
#需求将一个ip地址转换成一个32位的二进制数,并将其转换成一个10进制数输出.

  

ip = "192.168.1.1"

list_ip = []

for i in ip.split('.'):

    i_num = bin(int(i))

    i_num = "{:0>8}".format(i_num[2:])

    list_ip.append(i_num)

  

str_ip = "".join(list_ip)

print(str_ip)

print(int(str_ip,base=2))

4.6闭包:

4.6.1闭包的概念:

为函数创建一快区域并将其维护自己数据,以后执行是方便调用

4.6.2应用场景:

装饰器,SQL ALchemy源码

4.7装饰器:

4.7.1装饰器的目的

  • 在不改变原函数内部代码的基础上,在函数执行之前和之后自动执行某个功能.

4.7.2普通装饰器的编写格式:

def 外层函数(参数):
    def 内层函数(*args, **kwargs):
        #执行函数之前的内容
        return 参数(*args, **kwargs)
        #执行函数之后的内容
    return 内层函数

4.7.3普通装饰器应用格式:

@外层函数名
# 第一步:执行外层函数并将下面的函数参数传递,相当于:外层函数名(index)
#第二部:将fun的返回值从新赋值给下面的函数名,相当于index = 外层函数名(index)
def index():
    pass
index()

4.7.4普通装饰器的应用:

# 普通写法
import time

def fun1():
    time.sleep(1)

def fun2():
    time.sleep(1)

def fun3():
    time.sleep(1)

if __name__ == '__main__':
    # 测量 fun1 的运行时间
    start_time = time.time()
    fun1()
    end_time = time.time()
    run_time = end_time - start_time
    print(f'fun1 运行时间为: {run_time:.4f} 秒')

    # 测量 fun2 的运行时间
    start_time = time.time()
    fun2()
    end_time = time.time()
    run_time = end_time - start_time
    print(f'fun2 运行时间为: {run_time:.4f} 秒')

    # 测量 fun3 的运行时间
    start_time = time.time()
    fun3()
    end_time = time.time()
    run_time = end_time - start_time
    print(f'fun3 运行时间为: {run_time:.4f} 秒')

# 采用装饰器写法:
import time

def run_time(arg):
    def index(*args,**kwargs):
        start_time = time.time()
        arg()
        end_time = time.time()
        run_time = end_time - start_time
        print('运行时间为:%s' % run_time)
    return index
        
@run_time       
def fun1():
    time.sleep(1)
    pass
@run_time  
def fun2():
    time.sleep(1)
    pass
@run_time  
def fun3():
    time.sleep(1)
    pass

if __name__ == "__main__":
    fun1()
    fun2()
    fun3()

4.7.5带参数的装饰器的编写格式:

def outer(data):
    def wraper(func):
        def inner(*args, **kwargs):
            data = func(*args, **kwargs)
            return data
        return inner
    return wraper

4.7.6带参数的装饰器的应用格式:

@outer(data)
# 1执行 v1 = outer(data)
# 2执行 ret = v1(func)
# 3执行 func = ret
def func(*args, **kwargs):
    pass

4.7.7带参数装饰器的应用:

# 1需求通过装饰器传参,使某个函数运行多次
NUM = 1

def run_time(num):
    def wrapper(arg):
        def inner(*args, **kwargs):
            for i in range(num):
                arg()
        return inner
    return wrapper


@run_time(5)
def func():
    global NUM
    print(NUM)
    NUM += 1



func()

4.8递归

  • 递归效率低.默认的递归最大次数为1000,查看方法如下:
import sys
result = sys.getrecursionlimit()
print(result)
  • 递归的应用
#计算n的阶乘
def a(n):
    if n == 1:
        return 1
    else:
        n = n * a(n - 1)
    return n


print(a(10))

五.模块

5.1 hashlib:

5.1.1 md5加密

# md5加密
import hashlib
obj = hashlib.md5('醋'.encode('utf-8'))  # 加盐
obj.update('xx'.encode('utf-8'))
result = obj.hexdigest()
print(result)

5.2getpass

5.2.1密码不显示

pycharm中能够显示,只能在终端中才能不显示.

#密码不显示
import getpass
pwd = getpass.getpass("请输入密码:")
print(pwd)

5.3random:

5.3.1随机生成整数:

import random
print(random.randint(0,10))

5.4 os

5.4.1判断路径是否存在

import os
print(os.path.exists('路径地址'))  # 找到返回true,找不到返回false 

5.4.2获取文件的大小

import os

path = './data.txt'
print(os.stat(path).st_size)

5.4.3 获取文件的决定路径

import os

print(os.path.abspath('./data.txt'))

5.4.4 获取路径的上级目录

import os

print(os.path.dirname('C:\\Users\\lingview\\Desktop\\test.txt'))

5.4.5目录的拼接(重点)

import os

print(os.path.join('C:\\Users\\lingview','Desktop\\test.txt'))

5.4.6 获取一个目录下的所有文件(只有一层)

import os

print(os.listdir('.')) 

5.4.7 获取一个目录下的所有文件(重点+面试题)

import os

for a,b,c in os.walk('.'):
    for item in c:
        path = os.path.join(a,item)
        print(path)

5.4.8 创建目录

import os

file_path = '.'
file_name = '123'
path = os.path.join(file_path,file_name)
if not os.path.exists(path):
    os.mkdir('123')  # 只能创建一层目录
    os.makedirs('123/456')  # 创建多层目录

5.4.9 重命名

import os

old_name = 'data.txt'
new_name = 'test.txt'

os.rename(old_name, new_name)

5.5 sys:

5.5.1 sys.argv 获取传参

import sys

print(sys.argv) 

5.5.2 sys.getrefcount 获取内存变量的调用次数

import sys

a = [11,22]
print(a)
print(sys.getrefcount(a))  # 2

5.5.3 sys.getrecursionlimit 获取递归的最大值

import sys

print(sys.getrecursionlimit())

5.5.4 sys.path 编译器环境变量(重点)

import sys

# 获取编译器的环境变量
print("原始 sys.path:", sys.path)

# 添加环境变量
new_path = 'C:\\Users\\lingview'
sys.path.append(new_path)
print("添加路径后的 sys.path:", sys.path)

# 移除环境变量
try:
    sys.path.remove(new_path)
    print("移除路径后的 sys.path:", sys.path)
except ValueError:
    print(f"路径 {new_path} 不存在于 sys.path 中")

5.5.5 sys.exit 退出程序

import sys
sys.exit()

5.6 shutil

5.6.1 删除目录

import shutil

path = './test'
shutil.rmtree(path)

5.6.2 重命名

import shutil
shutil.move('123','data')

5.6.3 压缩文件

import shutil
file_name = 'hello.txt'
format = 'zip'
shutil.make_archive(file_name, format=format)

5.6.4解压文件

import shutil

file_path = 'hello.zip'
shutil.unpack_archive(file_path, format='zip', extract_dir='world')

5.6.5 练习题

# 练习题:
# 压缩data文件夹 放到code文件夹中(默认不存在) 并将文件解压到桌面code文件中
import os
import shutil

if not os.path.exists('code'):
    os.mkdir('code')

shutil.make_archive(base_name='./code/data',format='zip',root_dir='data')
shutil.unpack_archive(filename='./code/data.zip',format='zip',extract_dir='test')

5.7 json

5.7.1 json基础知识

  • json 是一个特殊的字符串,字符串最外层必须是列表或字典,
  • 字符串中的字符串必须用双引号
  • 布尔值全部为小写否则报错
  • json中不能出现集合

5.7.2 序列化

import json

stra = [123,{1:456},"hello",[445,5,3],True]
a  = json.dumps(stra)  # 将python数据转换为json数据,如果存在中文,或变成unicode编码的字节

# 序列化保留中文,需要传入一个关键字参数ensure_ascii=False
a = json.dumps(stra,ensure_ascii=False)
print(a)

5.7.3反序列化

import json

stra = '[123,{"1":456},"hello",[445,5,3],true]'
b  = json.loads(stra)  # 将json数据转换为python数据
print(b)

5.8 pickle模块

5.8.1 pickle与json的区别

  • pickle 和 json 都是做序列化
  • json:优:所有的语言通用,缺点:只能序列化基本的数据类型
  • pickle:优:python中的所有的东西都可以被序列化(套接字对象除外),缺点:序列化的内容只有python能够识别.

5.8.2 序列化和反序列化

import pickle
def run():
    print('hello word!')

# 序列化
v = pickle.dumps(run)
print(v)

# 反序列化
y  = pickle.loads(v)
y()

5.9 datetime模块

import time
from datetime import datetime, timedelta, timezone

# 获取当前时间
time1 = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print("当前时间 (本地):", time1)

# 获取UTC时间
time2 = datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M:%S')
print("UTC时间:", time2)

# 获取某个时区的时间 (东7区)
t = timezone(timedelta(hours=8))  # 东是正 西是负
time3 = datetime.now(t).strftime('%Y-%m-%d %H:%M:%S')
print("东7区时间:", time3)

# 将datetime.datetime装换成字符串
time4 = datetime.now()
print("当前时间 (datetime对象):", type(time4))
time5 = time4.strftime('%Y-%m-%d %H:%M:%S')
print("当前时间 (字符串):", time5)

# 将str装换成datetime.datetime类型
str1 = '2019-11-30 14:52:33'
time6 = datetime.strptime(str1, '%Y-%m-%d %H:%M:%S')
print("字符串转换为datetime对象:", time6, type(time6))

# datetime的加减
time7 = datetime.now()
time8 = time7 + timedelta(days=50)
print("当前时间加上50天:", time8)

# 时间戳转换datetime
time_t1 = time.time()
time9 = datetime.fromtimestamp(time_t1)
print("时间戳转换为datetime对象:", time9)

# datetime转换时间戳
time_t2 = time9.timestamp()
print("datetime对象转换为时间戳:", time_t2)

5.自定义模块及包的知识:

1.自定义模块

  • 定义模块时可以把一个py文件或一个文件夹(也叫作包)当作一个模块,以方便以后其他的py文件的调用
# 假设有一个包名称为haha 里面有一个hello.py文件  并且haha所在的路径已经添加到sys.path中
# 导入hello的方法1:
form cirrus import hello
#引用方法:
hello.xxx

# 方法2:
import cirrus.hello
#引用方法:
cirrus.hello.xxx
  • 注意:在导入模块或者包的时候,模块或包中所有的值都会被导入到内存中.

2.包的定义

  • py2中:文件夹里面必须有_ _ init _ _.py
  • py3中:不需要_ _ init _ _ .py,但推荐加上
  • _ _ file _ _变量可以直接获取到python运行时的文件路径参数

3.包的安装方法:

  1. pip包管理工具
  2. 源码安装
    1. 下载源码包,是一个压缩文件
    2. 解压文件
    3. 终端进入解压的路径
    4. 执行python setup.py build
    5. 执行python setup.py install

4.导入包:

# 假设存在一个包名称为xxx,里面包含jd.py....
import xxx
from xxx import *
# 以上2种导入全部都是导入的包里面的__init__.py文件,并不能去导入其他的模块
import xxx.jd
from xxx import jd
# 这样可以导入包里面的某一个模块

六.异常处理及多任务相关内容

1.异常处理的基本写法

try:
    v = 12 + "str"
except Exception as e:
    print('异常处理')

2.迭代器

  • 迭代器帮助你对某种对象中的元素进行逐一获取

2.1创建迭代器

list1 = [11,22,33,44]
# 方法1
list2 = list1.__iter__()

# 方法2
list3 = iter(list1)

2.2调用迭代器的值

v = [11,22,33,44].__iter__()
# 方法1
v.__next__() # 取值时取完最后一个再去取值时则会报错
# 方法2 
for i in v:
    pass

2.3可迭代对象

  • 具有__intr____next__或者能够能够语用于for循环

3.生成器

3.1创建生成器

# 如果一个函数中出现了yield关键字,该函数就是一个生成器的模板
def fun():
    yield 1
 
v = fun() # 创建生成器

3.2调用生成器的值

# 如果一个函数中出现了yield关键字,该函数就是一个生成器的模板
def fun():
    yield 1
    yield 2
    yield 3

# 创建生成器
v = fun()

# 迭代生成器并打印其值
for value in v:
    print(value)

3.3调用生成器的值并获取return的结果

def fun():
    a = yield 1
    b = yield 2
    c = yield 3
    return a, b, c

v = fun()
i = 1

# 启动生成器
next(v)

while True:
    try:
        result = v.send(i)
        print(result)
        i += 1
    except StopIteration as e:
        print(e.value)
        break

3.4生成器推导式

v1 = [lambda i=i: i for i in range(10)]  # 列表推导式,每个lambda捕获当前的i值
v2 = (lambda i=i: i for i in range(10))  # 生成器推导式,每个lambda捕获当前的i值
for i in v1:
    print(i())  # 输出0, 1, 2, 3, 4, 5, 6, 7, 8, 9
for i in v2:
    print(i())  # 输出0, 1, 2, 3, 4, 5, 6, 7, 8, 9
 

评论