python列表解析的底层详解

python列表解析的底层详解,第1张

python列表解析的底层详解

python列表解析的底层详解
      • 1.什么是列表解析
      • 2.为什么要使用列表解析
        • (1).简洁
        • (2).速度更快
      • 3.怎样使用列表解析
        • (1). 一维情况
        • (2). 多维情况(以三维为例)
        • (3).列表运算
      • 3.列表解析内存问题

1.什么是列表解析

python列表解析,英文表示 List Comprehensions,就是列表推导的意思,推导出我们想要的列表,它是一种创造列表的方式,常见的用途,创建列表、替代for循环

2.为什么要使用列表解析 (1).简洁

python的官方文档中,关于介绍列表解析的第一句话就是,

List comprehensions provide a concise way to create lists.
列表解析提供了一种简洁的方式去创建列表。

我们举个例子感受一下:
常规 *** 作:

x = list(range(100))
y = []
for i in x:
    y.append(i**2+i*2+1)

列表解析:

x = list(range(100))
y = [i**2+i*2+1 for i in x]

二维情况:

x = list(range(100))
y = list(range(100))
z = []
for i in x:
    for j in y:
        if(i!=j):
            z.append([i,j])
x = list(range(100))
y = list(range(100))
z = [[i,j] for i in x for j in y if i!=j]
(2).速度更快

当然这种快,不是再任何情况下都更快,在大数据的运算中,列表解析的速度是要比循环的速度更快,
因为列表解析的底层是C语言写的,速度很快,而for循环是在python虚拟机中以步进的方式运行的。
下面举个例子:

import math
import time

start = time.time()
x = list(range(100000000))  #同时读取1亿个数据
y = [i*3+math.sqrt(i)+1 for i in x]
end = time.time()
print(end-start)


start = time.time()
x = list(range(100000000))
y = []
for i in x:
    y.append(i*3+math.sqrt(i)+1)   
end = time.time()

print(end-start)

result:

列表解析的速度大约是for循环的1.5倍。

3.怎样使用列表解析 (1). 一维情况
x = list(range(100))
y = []
for i in x:
    y.append(i**2+i*2+1)

比如上面这个例子,只需要将for循环的整体放入列表解析的方框中,然后在最前面加上循环表达式即可,
公式 : listComprehension = [ i表达式 for i in 可迭代对象]

(2). 多维情况(以三维为例)
x = list(range(100))
y = list(range(100))
z = list(range(100))
ans = []

for i in x:
    for j in y:
        for k in z:
            ans.append([i,j,k])
ans = [[i,j,k] for i in x for j in y for k in z]

多维情况只需要按顺序写就行。

(3).列表运算

这种情况会经常遇到,比如两个列表,现在需要对应元素相加或者相乘。

sumxy = [i+j for i,j in zip(x,y)] #列表相加
sumxy = [i+j for i,j in zip(x,y)] #列表相乘
sumxyz = [i*j*k for i,j,k in zip(x,y,z) #三个列表相乘] 
# zip函数,可以将多个列表转变为一个zip对象,里面是一组元组。

3.列表解析内存问题
for i in range(9,11):
    a = [i for i in range(i)]   #for循环体和列表解析中的i重名,但此时i只会取到i-1,那解析对循环有影响吗?
    print(i)

上面这个例子,for循环体和列表解析中的i重名,那两者有无影响,这个问题比较有意思,因为range(i)实际数值只会到i-1,所以i会变为i-1,所以按常识来说,最后输出应为,8,9,but:

解析对循环无影响,即使两者的循环变量相同,都是i,因为列表解析中的循环变量存在于一个单独的内存,并在运算完成后删除,换句话说,这个i换成任意标识符都是可以的,不会影响for循环中的i,但在编程中一定要避免这种现象。

在运行列表解析中,循环变量i,并不会存在内存中,因为这个通过c底层执行,与python解释器不在一块,所以这个列表解析的循环变量和for的循环变量不在一个内存中,for中的i只是c运行内存中的输入变量,c内存中的运算并不会改变for中的循环变量值,这就好比局部变量和全局变量,for中的i是全局变量,列表解析中的i循环只是局部变量罢了。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5479413.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存