1.19 转�并�时计算数�¶

问题¶

你需�在数��列上执行�集函数(比如 sum() , min() , max() ), 但是首先你需�先转�或者过滤数�

解决方案¶

一个�常优雅的方�去结�数�计算与转�就是使用一个生�器表达��数。 比如,如果你想计算平方和,�以�下�这样�:

nums = [1, 2, 3, 4, 5]
s = sum(x * x for x in nums)

下�是更多的例�:

# Determine if any .py files exist in a directory
import os
files = os.listdir('dirname')
if any(name.endswith('.py') for name in files):
    print('There be python!')
else:
    print('Sorry, no python.')
# Output a tuple as CSV
s = ('ACME', 50, 123.45)
print(','.join(str(x) for x in s))
# Data reduction across fields of a data structure
portfolio = [
    {'name':'GOOG', 'shares': 50},
    {'name':'YHOO', 'shares': 75},
    {'name':'AOL', 'shares': 20},
    {'name':'SCOX', 'shares': 65}
]
min_shares = min(s['shares'] for s in portfolio)

讨论¶

上�的示例�你演示了当生�器表达�作为一个�独�数传递给函数时候的巧妙语法(你并�需�多加一个括�)。 比如,下�这些语�是等效的:

s = sum((x * x for x in nums)) # 显�的传递一个生�器表达�对象
s = sum(x * x for x in nums) # 更加优雅的实现方�,�略了括�

使用一个生�器表达�作为�数会比先创建一个临时列表更加高效和优雅。 比如,如果你�使用生�器表达�的�,你�能会考虑使用下�的实现方�:

nums = [1, 2, 3, 4, 5]
s = sum([x * x for x in nums])

这�方��样�以达到想�的效果,但是它会多一个步骤,先创建一个�外的列表。 对于�型列表�能没什么关系,但是如果元素数��常大的时候, 它会创建一个巨大的仅仅被使用一次就被丢弃的临时数�结构。而生�器方案会以迭代的方�转�数�,因此更�内存。

在使用一些�集函数比如 min() 和 max() 的时候你�能更加倾�于使用生�器版本, 它们接�的一个 key 关键字�数或许对你很有帮助。 比如,在上�的�券例�中,你�能会考虑下�的实现版本:

# Original: Returns 20
min_shares = min(s['shares'] for s in portfolio)
# Alternative: Returns {'name': 'AOL', 'shares': 20}
min_shares = min(portfolio, key=lambda s: s['shares'])