Python 列表解析

本文详细介绍了Python中的三元表达式和列表解析式,包括它们的语法、用法及优缺点。通过示例展示了如何使用三元表达式简化条件判断,并演示了列表解析式的两种语法形式,以及其在性能和内存占用上的优势。同时,提到了生成器表达式在处理大量数据时的高效性。文章还讨论了列表解析和生成器表达式的应用场景和局限性。
摘要由CSDN通过智能技术生成

一、三元表达式

x = 3
y = 4
if x > y:
	res = x
else:
	res = y

用单元表达式替换

x = 3
y = 4
res= x if x > y else y

三元表达式的最左边和最右边可以写成任意表达式

x = 3
y = 4
res = 'aaa' if x >y eles 'bbb'

二、列表解析式

1.语法一

[expression for item1 in iterable1 ]
expression 可为变量或者表达式

源代码:

s=[]
for i in 'hello':
	s.append(i.upper())

等价于:

s=[i.upper() for i in 'hello']

说明:for 循环得到的每一个元素返回给 for 前面的 i 变量,然后执行 upper 函数,将执行结果以列表的形式返回~。相比于 for 循环,列表解析的语法由 c语言实现,性能会有所提升

2.语法二

[expression for item1 in iterable1 if condition1
                    for item2 in iterable2 if condition2
                    .....
                    for itemN in iterableN if conditionN
        ]

等价于

类似于

res=[]
for item1 in iterable1:
    if condition1:
        for item2 in iterable2:
             if condition2:
                ......
                for itemN in iterableN:
                     if conditionN:
                            res.append(expression)

示例:

lst = [1,2,60,67,34,78,98,70,89]
data=[ i for i in lst if i>50]

绝大多数的情况,列表解析仅使用一层循环,即

[expression for item in iterable if condition]

结合三元表达式

上面已经给出列表解析的语法,for 循环前面的 expression 可以是一个变量,也可以是一个表达式,看如下示例,列表中的×××(int)原样取出,若是浮点类型(float),则进行四舍五入后取出:

a = [1,2,3.2,1.3,5.9]
res = [i if isinstance(i, int) else int(round(i)) for i in a]

res : [1, 2, 3, 1, 6]

这里 for 循环前的 expression 是一个三元表达式,判断语句在三元表达式中实现

全0列表

for 循环前的 expression 也可以是一个 常量,例如要获取一个固定长度的,且都是某个值的列表:

lst = [0 for i in range(10)]    # 长度为10,全为0 的列表

lst : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

– 复杂的列表解析

列表解析多层 for 循环示例,读取列表中每个单词的字母,并生成一个新的列表:

lst = ['hello', 'kitty']
res = [l for word in lst for l in word]

res : ['h', 'e', 'l', 'l', 'o', 'k', 'i', 't', 't', 'y']

如上示例可能一下子难以理解,根据列表解析的语法:

[expression for item1 in iterable1 if condition1
                    for item2 in iterable2 if condition2
                    .....
                    for itemN in iterableN if conditionN
        ]

类似于

res=[]
for item1 in iterable1:
    if condition1:
        for item2 in iterable2:
             if condition2:
                ......
                for itemN in iterableN:
                     if conditionN:
                            res.append(expression)

如上示例使用 for 循环表示:

res = []
for word in lst:
    for l in word:
        res.append(l)

print(res)

输出结果:
['h', 'e', 'l', 'l', 'o', 'k', 'i', 't', 't', 'y']

列表解析并没有降低代码的可读性,且缩小了代码量、提升了性能,但是若其中出现多层 for 循环嵌套,可能会降低代码的可读性,不易于理解

2.生成器表达式

列表解析会一次性的生成所有的数据,然后加载到内存中,然后生成列表对象,这样不适用迭代大量的数据,而生成器恰好解决了这个问题。

2.1语法

(expression for item1 in iterable1 if condition1
                    for item2 in iterable2 if condition2
                    .....
                    for itemN in iterableN if conditionN
       )

示例:
>>> g = (i for i in range(100))
>>> g
<generator object <genexpr> at 0x00000288D8C9A308>

若使用生成器表达式,所有的数据不会一次性全部加载到内存中,而是按照从前向后的顺序,用到一个加载一个。当数据量比较大时,更节省内存~

import time

start_time = time.time()
g = (i for i in range(100000000))
stop_time = time.time()
print('run time is %s' % (stop_time - start_time))

print(next(g))
print(next(g))
print(next(g))

输出结果:

run time is 0.0        # 得到生成器 g 的用时~
0
1
2

同样的数据量使用列表解析,会消耗相当长的时间,若是再加几个0,程序可能就会卡住:

import time

start_time = time.time()
lst = [i for i in range(100000000)]
stop_time = time.time()
print('run time is %s' % (stop_time - start_time))

lst_iter = lst.__iter__()
print(next(lst_iter))
print(next(lst_iter))
print(next(lst_iter))

输出结果:

run time is 5.407538890838623     # 生成列表的时长
0
1
2

当然生成器表达式也有缺点,由于生成器表达式返回的是一个生成器,所以若要迭代所有的元素,只能从前往后挨个迭代;而列表解析返回的是列表,可以根据索引立即返回指定位置的元素

gen = (i for i in range(100))
print(gen[10])             # 错误

lst = [i for i in range(100)]
print(lst[10])                  # 没有问题
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值