生成式的使用

  • 一、字符串生成式
  • 二、元组生成式
  • 三、列表生成式
  • 3.1 生成
  • 3.2 if 语句
  • 3.3 if-else 语句
  • 四、集合生成式
  • 五、字典生成式
  • 六、其他对象生成式

  生成式(comprehensions),又叫推导式,是 python 中生成有规律的数据的一种简洁表示方法,如何使用一行代码的生成式来推导所需的数据是面试中经常遇到的问题。

  注意:

python 中列表生成式是最基本的生成式,其他生成式都可以在列表生成式的基础上转化得到

一、字符串生成式

字符串生成器可以通过列表生成器实现:

>>> string = "".join([chr(i) for i in range(97,123)]) 
>>> string
'abcdefghijklmnopqrstuvwxyz'

或者可以配合 ord 函数使用:

>>> "".join([chr(i) for i in range(ord("A"), ord("Z")+1)]) 
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

二、元组生成式

元组生成器也是通过列表生成器实现:

>>> tup = tuple([i for i in range(5)]) 
>>> tup
(0, 1, 2, 3, 4)
>>> type(tup)
<class 'tuple'>

三、列表生成式

3.1 生成

列表生成器可以使用生成器(如 range 等)或其他可迭代对象来生成:

>>> [i**2 for i in [0,1,2,3,4]]
[0, 1, 4, 9, 16]
>>> [i**2 for i in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

3.2 if 语句

列表生成器还可以和 if 函数配合使用:
如果 if 函数在后,表示对 for 遍历结果的筛选:

>>> [i for i in range(10) if i%2==1]
[1, 3, 5, 7, 9]

3.3 if-else 语句

如果 if 函数在前,则表示对 for 的遍历结果执行不同的操作,此时必须加上 else 语句:

# 奇变偶不变
>>> [i**2 if i%2==1 else i for i in range(10)] 
[0, 1, 2, 9, 4, 25, 6, 49, 8, 81]

这种情况可以理解为对 for 遍历的结果执行三元运算,故也可以使用 lambda 函数实现:

>>> [(lambda x:x**2 if x%2==1 else x)(i) for i in range(10)] 
[0, 1, 2, 9, 4, 25, 6, 49, 8, 81]

列表生成式还可以通过生成器实现:

>>> list(map(lambda x:x**2 if x%2==1 else x, range(10)))        
[0, 1, 2, 9, 4, 25, 6, 49, 8, 81]

四、集合生成式

只需要改变生成式外层的符号为 “{}” 即可:

>>> [i for i in range(10) if i%2==1]
[1, 3, 5, 7, 9]

当然,也可以由列表生成式转化得到:

>>> set([i for i in range(10) if i%2==0]) 
{0, 2, 4, 6, 8}

最后,还能从生成式转化得到:

>>> set(i for i in range(10) if i%2==0) 
{0, 2, 4, 6, 8}

五、字典生成式

也是使用 “{}” 直接生成,但里面放的是 “k:v” 键值对:

>>> {i:i**2 for i in range(10)} 
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

也可以从列表中提取数据生成字典:

>>> {i:j for (i,j) in [(1,1),(2,4),(3,9)]}  
{1: 1, 2: 4, 3: 9}

六、其他对象生成式

对于简单的类来说,也是可以通过生成式来实现简易的生成的。
定义一个类 Person:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

生成类的列表:

names = ["张三", "李四", "王二", "麻子"]
ages = [34, 23, 56, 17]
person_list = [Person(names[i], ages[i]) for i in range(len(names))]

查看列表中的类元素:

for person in person_list:
    print(f"name:{person.name}, age:{person.age}")
# name:张三, age:34
# name:李四, age:23
# name:王二, age:56
# name:麻子, age:17