列表(生成)推导式

我们有一个需求,输出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'}

是的,这样确实可以,但是这个灵活性不好,它不允许我们添加我们自己的业务逻辑,而上面那种却是万能的。