用到函数的一个常见操作是将其用于一个列表的所有项,并使用结果来创建一个新的列表。
1.列表的生成式
如果我们要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]能用哪种方法呢?当然最基础的方法可以参见列表(上) 但是,这种只适合项比较少的一些场景,现在我们要生成1到999的列表怎么办呢?
list(range(1,11)) #生成的结果不包含11,只是1到10的区间,前开后闭
接下来再加点复杂的成分,生成一个[1x1, 2x2, 3x3, …, 10x10]这样的列表怎么做呢?
#方法一:
l = []
for x in range(1, 11)
L.append(x * x)
#方法二:
L = [x * x for x in range(1, 11)]
#还可以加上if判断做筛选
L = [x * x for x in range(1, 11) if x % 2 != 0] #筛选出奇数的平方
L = [x * x for x in range(1, 11) if x % 2 == 0] #筛选出偶数的平方
#除了生成上述列表外,还可以列出当前目录下的所有文件和目录名,通过一行代码实现:
import os
P = [d for d in os.listdir('.')]
2.列表推导的一些扩展
#将字典转换为列表
dict1 = {
'name' : 'Allen',
'age' : '18',
'valude' : '66'
}
T = [a + '=' + b for a , b in dict1.items()]
print(T)
3.列表推导的一般语法
[expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
...
for itemN in iterableN if conditionN]
if子句是可选的,但是如果使用它,那么只有condition为真的时候才会对expression求值并添加到结果中
4.生成器表达式
生成器表达式是一个对象,它执行的计算与列表推导相同,但是迭代地生成结果。他的语法也是与列表推导相同,但是要用元括号替代方括号。当然和列表推导不同的是,生成器表达式不会创建序列形式的对象。你不能对它进行任何索引,也不能进行任何常规操作。但是使用内置的list()函数可以将生成器表达式转换为列表。clist = list(comments)
和列表推导不同,生成器表达式实际上不创建列表或者立即对圆括号内的表达式求值。相反,它会创建一个生成器对象,该对象通过迭代并按照需要生成值,如下代码:
a = [1, 2, 3, 4]
b = (10 * i for i in a)
>>> b.__next__()
10
>>> b.__next__()
20
>>> b.__next__()
30
>>> b.__next__()
40
生成器表达式的一些实战用法
#读取一个文件
f = open("data.txt") #打开一个文件
lines = (t.strip() for t in f) #读取行,并删除前后空白
comments = (t for t in lines if t[0] == '#') #所有注释
for c in comments:
print(c)
在这段代码中生成器表达式提取各行并删除其中空白,但它实际上没有将整个文件读取到内存中。提取注释的表达式也是如此。相反,当程序开始在for循环中进行迭代时,才会去读取文件的各行。在这个迭代的过程中,每一行都是按需生成的,按条件进行过滤。事实上,该过程从未把整个文件加载到内存中。因此,这是一种从GB级别大小的Python源文件中提取注释的高效方法。.
总结
- 本节我们学习了列表推导的相关概念,结合实际例子讲述了列表推导的语法。
- 在第四节中进行了一些拓展并学习了生成器表达式的使用以及一些有用的实践