《Python一行流》学习笔记4——其他一些技巧

1 列表连接(list concatenation)  

        用 + 运算符连接现有的列表来获得一个新列表,但不会替换掉原来的列表

list1 = [1, 2, 3]
list2 = [4, 5, 6]
print(list1 + list2)    # [1, 2, 3, 4, 5, 6]

print(list1)    # [1, 2, 3]

print(list2)    #[4, 5, 6]

        用 * 运算符可以进行多重连接,这样就能快速地创建出很长的列表,其同样不会替换原来的列表

list1 = [1, 2, 3]

print(list1 * 3)    # [1, 2, 3, 1, 2, 3, 1, 2, 3]

print(list1)    # [1, 2, 3]

2 生成器表达式(generator expressions)

        生成器表达式——一种列表解析的更泛化的形式,其与列表解析的工作方式一样名单不需要在内存中真的去创建一个列表。遍历到的元素是在运行时临时生成的,而没有显式存储在一个列表中。

# 计算前20个自然数平方和
# 列表解析法:会先一次性把前20个自然数的平方存储在一个列表中,然后再进行求和
sum([x * x for x in range(20)]

# 生成器表达式法:每算出一个自然数的平方就进行将其与前面的总和进行相加
sum(x * x for x in range(20)]

         给定一个字典,其存储了公司员工的时薪。现在要求你提取出一个公司列表,代表那些至少给一个员工支付了低于最低工资标准(<$9)的公司。

# 数据
companies = {
    'CoolCompany': {'Alice': 33, 'Bob': 28, 'Frank': 29},
    'CheapCompany': {'Ann': 4, 'Lee': 9, 'Chrisi': 7},
    'SosoCompany': {'Esther': 38, 'Cole': 8, 'Paris': 18},
}

# 一行流
illegal = [x for x in companies if any(y < 9 for y in companies[x].values())]
'''
1、这个一行流程序使用了两个生成器表达式
(1)第一个生成器表达式:y < 9 for y in companies[x].values() 用于产生输入给函数 
    any()的数据。这个表达式检查了公司的每个员工,看他们的工资 y 时候小于9(y<9),得到
    一个由布尔值组成的可迭代对象。这里还是用了字典方法 values() 来返回存在字典中的值
    的列表。如果他们中至少有一个低于最低工资标准,函数 any() 将返回 True,该公司 x 将
    会作为字符串存在结果列表 illegal 中。
(2)第二个生成器表达式:[x for x in companies if any(...)],它创建一个公司名称列表,
    包含了之前的 any() 调用中的恶道结果为 True 的公司名称。
2、any()函数:其接收一个可迭代对象,如果这个可迭代对象中至少有一个为真值,则返回True;
    否则返回 False
'''

# 结果:
print(illegal)
# ['CheapCompany', 'SosoCompany']

3 zip() 函数

        zip() 函数接收一系列可迭代对象 iter_1, iter_2,..., iter_n 作为参数,并把它们聚合成一个可迭代对象。方式是先把它们对齐——自动压缩可迭代对象参数的长度使其与最短的可迭代对象参数的长度一致,然后把每个可迭代对象的第 i 个元素取出来放到一个元组中,最后返回这些元组构成的可迭代对象。

       

list1 = [1, 2, 3]
list2 = [4, 5]

# 把两个列表压缩到一起
zipped = list(zip(list1, list2))
# 如果不使用 list() 函数将其转换成列表对象,将生成 zip 对象

print(zipped)
# [(1, 4), (2, 5)]

# 重新压缩回列表
list1_new, list2_new = zip(*zipped)
# 使用 * 运算符把列表拆解成元素。这个操作符的作用是去掉列表的外括号,
# 即*zipped 操作回生成2个可迭代对象——元组,zip()函数会对其进行一次压缩
print(*zipped)  # (1, 4) (2, 5)

print(list1_new)    # (1, 2)
print(list2_new)    # (4, 5)

        zip() 函数并不会在意一个参数是列表而另一个参数是元组,它只要求输入的是可迭代对象即可,即你可以混合使用它们。       

        现有一份数据,其包含全部字段名称,以及用元组的列表组织的员工数据,每行是一个元组。现在要把字段名称添加到员工数据里,由此创建出一个由字典构成的列表,每个字典中将字段名分配给对应的值。

# 数据
column_names = ['name', 'salary', 'job']
db_rows = [('Alice', 180_000, 'data scientist'),
           ('Bob', 99_000, 'mid-level manager'),
           ('Frank', 87_000, 'CEO')]

# 一行流
db = [dict(zip(column_names, row)) for row in db_rows]
# 这里使用了列表解析来创建列表,上下文由变量 db_rows 中的每一行元组组成
# zip(column_names, row) 把字段名跟每一行数据压缩在一起
# dict()将列表中每个元素转换成 键: 值 的格式

# 结果
print(db)
# [{'name': 'Alice', 'salary': 180000, 'job': 'data scientist'},
# {'name': 'Bob', 'salary': 99000, 'job': 'mid-level manager'},
# {'name': 'Frank', 'salary': 87000, 'job': 'CEO'}]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值