列表(生成)推导式
我们有一个需求,输出10以内的所有奇数:
1 2 3 4 5 6 7 8 9 10
| old_list = [] for i in range(10): if i % 2 ==1: old_list.append(i)
print(old_list)
# 输出结果: [1, 3, 5, 7, 9]
|
现在我们对其进行修改,利用列表生成式来实现相同的功能:
1 2 3 4 5
| a = [i for i in range(10) if i % 2 ==1] print(a)
# 输出结果: [1, 3, 5, 7, 9]
|
是不是很简单,我们加一点困难,返回那些奇数的平方,同样也是使用列表生成式来完成:
1 2 3 4 5 6 7 8 9
| def sequreitem(item): return item*item
a = [sequreitem(i) for i in range(10) if i % 2 ==1] b = [i**2 for i in range(10) if i % 2 == 1] print(a) print(b)
|
这样看起来也是很简单的,但是一旦有更多的逻辑,我们就不要用了,因为代码的可读性是非常重要的。列表生成式的性能高于列表操作,如果能用就尽量使用好了。
生成器表达式
首先我们不要轻易理解()为tuple或者set,有了这一点后面就好说了。我们尝试将[sequreitem(i) for i in range(10) if i % 2 ==1]
里面的[ ]修改为(),然后我们对比打印输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
def sequreitem(item): return item*item
a = [sequreitem(i) for i in range(10) if i % 2 ==1] print(type(a)) print(a)
b = (sequreitem(i) for i in range(10) if i % 2 ==1) print(type(b)) print(b)
# 输出结果: <class 'list'> [1, 9, 25, 49, 81]
<class 'generator'> <generator object <genexpr> at 0x00EE2630>
|
看到没,我们通过把[ ]修改为(),然后就把一个list对象转变成了一个generator对象,然后输出打印的只是他它在内存中的地址。我们可以利用list()方法,将生成器转变成list:
1 2 3 4 5 6
| b = (sequreitem(i) for i in range(10) if i % 2 ==1) print(type(b)) print(list(b))
# 输出结果: [1, 9, 25, 49, 81]
|
字典推导式
字典推导式和我们的列表生成式非常相似,我们现在需要将下面字典中的key与value进行对换:
1 2 3 4 5 6 7 8 9
| dict_test = { "Tom":89, "Jan":90, "Bob":93, "Jac":100} reversed_dict = { value:key for key,value in dict_test.items()} print(type(reversed_dict)) print(reversed_dict)
# 输出结果: <class 'dict'> {89: 'Tom', 90: 'Jan', 93: 'Bob', 100: 'Jac'}
|
集合推导式
集合推导式和我们的字典生成式非常相似,我们现在需要将上面字典中的key单独分开,成为一个集合:
1 2 3 4 5 6 7
| set_test = { key for key,value in dict_test.items()} # 注意这里不能只写key,不写value print(type(set_test)) print(set_test)
# 输出结果: <class 'set'> {'Jac', 'Tom', 'Jan', 'Bob'}
|
有人说这样做太麻烦了,可以使用这个:
1 2 3 4 5 6 7
| set_tt = {key for key in dict_test.keys()} print(type(set_tt)) print(set_tt)
# 输出结果: <class 'set'> {'Jac', 'Tom', 'Jan', 'Bob'}
|
是的,这样确实可以,但是这个灵活性不好,它不允许我们添加我们自己的业务逻辑,而上面那种却是万能的。