京公网安备 11010802034615号
经营许可证编号:京B2-20210330
python列表生成式与列表生成器的使用
列表生成式:会将所有的结果全部计算出来,把结果存放到内存中,如果列表中数据比较多,就会占用过多的内存空间,可能会导致MemoryError内存错误或者导致程序在运行时出现卡顿的情况
列表生成器:会创建一个列表生成器对象,不会一次性的把所有结果都计算出来,如果需要获取数据,可以使用next()函数来获取,但是需要注意,一旦next()函数获取不到数据,会导致出现StopIteration异常错误,可以使用for循环遍历列表生成器,获取所有数据
需要视情况而定,如果数据量比较大,推荐使用生成器
python2.7中就是range(生成式) 和 xrange(生成器)的区别
列表生成式是快速生成一个列表的一些公式
在列表中存放0~100的数:
普通的列表生成:
numbers=[]
for x in range(0,101):
numbers.append(x)
print(numbers)
用列表生成式生成列表:[要放入列表的数据 简单的表达式1 表达式2]
#x for x in range(0,101) for循环遍历出来的值,放入列表中
numbers=[x for x in range(0,101)]
print(numbers)
列表中存放0~100的偶数:
普通方法生成列表:
for x in range(0,101):
if x%2==0:
numbers.append(x)
print(numbers)
用列表生成式生成列表:
#for循环遍历0~101的数字,如果数字对2取余==0,表示是偶数,x放在列表中
numbers=[x for x in range(0,101)if x%2==0]
print(numbers)
找出列表list1=['asd','adf','dafg','acbo']带有a的字符
普通写法:
rs_list=[]
for s in list1:
if 'a' in s:
rs_list.append(s)
print(rs_list)
列表生成式:
list2=[x for x in list1 if 'a' in x]
列表生成式支持双层for循环
list3=[x*y for x in range(0,10) for y in range(20)]
print(list3)
生成器构造实例
# 使用类似列表生成式的方式构造生成器
g1 = (2*n + 1 for n in range(3, 6))
# 使用包含yield的函数构造生成器
def my_range(start, end):
for n in range(start, end):
yield 2*n + 1
g2 = my_range(3, 6)
print(type(g1))
print(type(g2))
输出结果:
<class 'generator'>
<class 'generator'>
生成器的调用方式
要调用生成器产生新的元素,有两种方式:
调用内置的next()方法
使用循环对生成器对象进行遍历(推荐)
调用生成器对象的send()方法
实例1:使用next()方法遍历生成器
print(next(g1))
print(next(g1))
print(next(g1))
print(next(g1))
输出结果:
7
9
11
Traceback (most recent call last):
File "***/generator.py", line 26, in <module>
print(next(g1))
StopIteration
print(next(g2))
print(next(g2))
print(next(g2))
print(next(g2))
输出结果:
7
9
11
Traceback (most recent call last):
File "***/generator.py", line 31, in <module>
print(next(g2))
StopIteration
可见,使用next()方法遍历生成器时,最后是以抛出一个StopIeration异常终止。
实例2:使用循环遍历生成器
for x in g1:
print(x)
for x in g2:
print(x)
两个循环的输出结果是一样的:
7
9
11
可见,使用循环遍历生成器时比较简洁,且最后不会抛出一个StopIeration异常。因此使用循环的方式遍历生成器的方式才是被推荐的。
需要说明的是:如果生成器函数有返回值,要获取该返回值的话,只能通过在一个while循环中不断的next(),最后通过捕获StopIteration异常
实例3:调用生成器对象的send()方法
def my_range(start, end):
for n in range(start, end):
ret = yield 2*n + 1
print(ret)
g3 = my_range(3, 6)
print(g3.send(None))
print(g3.send('hello01'))
print(g3.send('hello02'))
输出结果:
7
hello01
9
hello02
11
print(next(g3))
print(next(g3))
print(next(g3))
输出结果:
7
None
9
None
11
结论:
next()会调用yield,但不给它传值
send()会调用yield,也会给它传值(该值将成为当前yield表达式的结果值)
需要注意的是:第一次调用生成器的send()方法时,参数只能为None,否则会抛出异常。当然也可以在调用send()方法之前先调用一次next()方法,目的是让生成器先进入yield表达式。
生成器与列表生成式对比
既然通过列表生成式就可以直接创建一个新的list,那么为什么还要有生成器存在呢?
因为列表生成式是直接创建一个新的list,它会一次性地把所有数据都存放到内存中,这会存在以下几个问题:
内存容量有限,因此列表容量是有限的;
当列表中的数据量很大时,会占用大量的内存空间,如果我们仅仅需要访问前面有限个元素时,就会造成内存资源的极大浪费;
当数据量很大时,列表生成式的返回时间会很慢;
而生成器中的元素是按照指定的算法推算出来的,只有调用时才生成相应的数据。这样就不必一次性地把所有数据都生成,从而节省了大量的内存空间,这使得其生成的元素个数几乎是没有限制的,并且操作的返回时间也是非常快速的(仅仅是创建一个变量而已)。
我们可以做个试验:对比一下生成一个1000万个数字的列表,分别看下用列表生成式和生成器时返回结果的时间和所占内存空间的大小:
import time
import sys
time_start = time.time()
g1 = [x for x in range(10000000)]
time_end = time.time()
print('列表生成式返回结果花费的时间: %s' % (time_end - time_start))
print('列表生成式返回结果占用内存大小:%s' % sys.getsizeof(g1))
def my_range(start, end):
for x in range(start, end):
yield x
time_start = time.time()
g2 = my_range(0, 10000000)
time_end = time.time()
print('生成器返回结果花费的时间: %s' % (time_end - time_start))
print('生成器返回结果占用内存大小:%s' % sys.getsizeof(g2))
输出结果:
列表生成式返回结果花费的时间: 0.8215489387512207
列表生成式返回结果占用内存大小:81528056
生成器返回结果花费的时间: 0.0
生成器返回结果占用内存大小:88
可见,生成器返回结果的时间几乎为0,结果所占内存空间的大小相对于列表生成器来说也要小的多。
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
近日,由 CDA 数据科学研究院重磅发布的《2026 全球数智化人才指数报告》,被中国教育科学研究院官方账号正式收录, ...
2026-04-22在数字化时代,客户每一次点击、浏览、下单、咨询等行为,都在传递其潜在需求与决策倾向——这些按时间顺序串联的行为轨迹,构成 ...
2026-04-22数据是数据分析、建模与业务决策的核心基石,而“数据清洗”作为数据预处理的核心环节,是打通数据从“原始杂乱”到“干净可用” ...
2026-04-22 很多数据分析师每天盯着GMV、转化率、DAU等数字看,但当被问到“什么是指标”“指标和维度有什么区别”“如何搭建一套完整的 ...
2026-04-22在数据分析与业务决策中,数据并非静止不变的数值,而是始终处于动态波动之中——股市收盘价的每日涨跌、企业月度销售额的起伏、 ...
2026-04-21在数据分析领域,当研究涉及多个自变量与多个因变量之间的复杂关联时,多变量一般线性分析(Multivariate General Linear Analys ...
2026-04-21很多数据分析师精通描述性统计,能熟练计算均值、中位数、标准差,但当被问到“用500个样本如何推断10万用户的真实满意度”“这 ...
2026-04-21在数据处理与分析的全流程中,日期数据是贯穿业务场景的核心维度之一——无论是业务报表统计、用户行为追踪,还是风控规则落地、 ...
2026-04-20在机器学习建模全流程中,特征工程是连接原始数据与模型效果的关键环节,而特征重要性分析则是特征工程的“灵魂”——它不仅能帮 ...
2026-04-20很多数据分析师沉迷于复杂的机器学习算法,却忽略了数据分析最基础也最核心的能力——描述性统计。事实上,80%的商业分析问题, ...
2026-04-20在数字化时代,数据已成为企业决策的核心驱动力,数据分析与数据挖掘作为解锁数据价值的关键手段,广泛应用于互联网、金融、医疗 ...
2026-04-17在数据处理、后端开发、报表生成与自动化脚本中,将 SQL 查询结果转换为字符串是一项高频且实用的操作。无论是拼接多行数据为逗 ...
2026-04-17面对一份上万行的销售明细表,要快速回答“哪个地区卖得最好”“哪款产品增长最快”“不同客户类型的购买力如何”——这些看似复 ...
2026-04-17数据分析师一天的工作,80% 的时间围绕表格结构数据展开。从一张销售明细表到一份完整的分析报告,表格结构数据贯穿始终。但你真 ...
2026-04-16在机器学习无监督学习领域,Kmeans聚类因其原理简洁、计算高效、可扩展性强的优势,成为数据聚类任务中的主流算法,广泛应用于用 ...
2026-04-16在机器学习建模实践中,特征工程是决定模型性能的核心环节之一。面对高维数据集,冗余特征、无关特征不仅会增加模型训练成本、延 ...
2026-04-16在数字化时代,用户是产品的核心资产,用户运营的本质的是通过科学的指标监测、分析与优化,实现“拉新、促活、留存、转化、复购 ...
2026-04-15在企业数字化转型、系统架构设计、数据治理与AI落地过程中,数据模型、本体模型、业务模型是三大核心基础模型,三者相互支撑、各 ...
2026-04-15数据分析师的一天,80%的时间花在表格数据上,但80%的坑也踩在表格数据上。 如果你分不清数值型和文本型的区别,不知道数据从哪 ...
2026-04-15在人工智能与机器学习落地过程中,模型质量直接决定了应用效果的优劣——无论是分类、回归、生成式模型,还是推荐、预测类模型, ...
2026-04-14