python列表生成器

列表生成器

列表生成器为创建列表提供了一种简洁的方式。其语法为

li = [f(var) for var in iterable if condition]

f(var)为变量var的表达式,f(var)为最终列表里每个结果的值

iterable为可遍历的数据结构,condition则为条件判断(condition也可没有)

当然还可以有多个变量var, 即可以有同时var1, var2, var3,也可以有多层for和多个判断if

我们通过例子深刻理解

比如说,我们可以将一个for循环变成列表用列表生成器的方式实现,简洁地实现一个平方数列表

Copysquares=[x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 其等效于
Copysquares = []
for x in range(10):
    Copysquares.append(x**2)

我们还可以在列表生成器中加入if语句

下列例子的功能是实现字符串分割且去除空格

s = 'hello world'
comp = [x for x in s if x != ' ']
# ['h','e','l','l','o','w','o','r','l','d']

# 其等效于
comp = []
for x in s:
    if x != ' ':
        comp.append(x)

当然我们还可以更复杂,使用两个for循环以及if判断

两个0-4范围内数,其中必须一个为偶数,另一个为奇数,返回相加的所有结果

add_ = 
[i+j for i in range(5) if i % 2 == 0 for j in range(5) if j % 2 == 1] 
# [1, 3, 3, 5, 5, 7]


# 其等效于
add_ = []
for i in range(5):
    if i % 2 == 0: # 当i为偶数时即0,2,4
        for j in range(5): 
            if j % 2 == 1: # 当j奇数时即1,3
                add_.append(i+j) 
# 计算顺序为 0+1,0+3,2+1,2+3,4+1,4+3
# 即[1, 3, 3, 5, 5, 7]

可以看到其实写列表生成器就像正常在写循环语句一样,主要区别有两个:

  1. 列表生成器将列表中的元素结果写到最前面
  2. 列表生成器中语句执行的顺序就是从左到右的顺序,只不过其将所有的for和if缩进和冒号都给省略了

实际上,列表生成式这个概念在Python中被泛化了。不但可以生成列表,还可以生成字典 dict 和集合 set。

字典生成器

字典生成器的语法为

dic = {key:value for key,value in iterable}

举例,将元组转换为dic

tup = [('zhang',0),('liu',1),('lan',2)]
dic = {k:v for k,v in tup}
print(dic)
# {'zhang': 0, 'liu': 1, 'lan': 2}

其实对于上面这个简单的例子,可以不用字典生成式,直接用 dict() 进行转换也是可以的。

但是当元组稍微复杂时,比如以下例子,元组中每个元组有三个值时,中间的为无效信息时,dict()就会有歧义,而我们的字典生成器更灵活

tup = [('zhang','s', 0),('liu','s',1),('lan','s',2)]
print(dict(tup))
# 报错 ValueError: dictionary update sequence element #0 has length 3; 2 is required

dic = {k:v for k,_,v in tup} # _ 跳过第二个元素
# {'zhang': 0, 'liu': 1, 'lan': 2}

最常用的场景就是在nlp场景中的word2idx和idx2word,需要双向都能找到对应的值,利用集合列表的索引和单词实现双向转换

vocab = ['love', 'milk', 'coffee', 'like', 'hate', 'cat', 'i']

word2idx = {w:i for i,w in enumerate(vocab)}
# {'love': 0, 'milk': 1, 'coffee': 2, 'like': 3, 'hate': 4, 'cat': 5, 'i': 6}

idx2word =  {i:w for i,w in enumerate(vocab)}
# {0: 'love', 1: 'milk', 2: 'coffee', 3: 'like', 4: 'hate', 5: 'cat', 6: 'i'}

还有一种常用的将字典中的键值对反转的场景,即key变value,value变key

Tips:要在遍历时同时用到key和value需要用到dic.items()

# 已知一个word2idx的词典,转化idx2word
word2idx = {'zhang': 1, 'liu': 2, 'lan': 3}

idx2word = {index:word for word,index in word2idx.items()}
# {1: 'zhang', 2: 'liu', 3: 'lan'}

集合生成器

集合生成器相对于来说就更简单了,其语法为

set_ =  {x for x in interable if condition}

比如要将句子转化为一个个字母词典且不需要空格时

s = 'hello world'
comp = {x for x in s if x != ' '}
# {'r', 'd', 'w', 'o', 'h', 'l', 'e'}
# 注意集合是无序的

type(comp)
# <class 'set'>

如果直接想要将s的各个元素转化为不重复的分隔字母且不在乎空格时,可以不用集合生成器,因为有更简单的用法,直接用set()即可

s = 'hello world'
comp = {x for x in s}
# {' ', 'r', 'o', 'd', 'e', 'h', 'l', 'w'}

# 直接用set就可以了!
comp = set(s)
# {' ', 'r', 'o', 'd', 'e', 'h', 'l', 'w'}结果一样
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值