序列求值的同时转换(过滤)数据

场景:需要执行缩减函数(例如,sum(),min(),max()),但首先需要转换或过滤数据。

通常可以使用生成器表达式进行数据的过滤,sum,min,max的参数为iterable,而generator继承iterator,iterator继承iterable。故生成器表达式同样可以作为这些函数的参数。
如下示例:

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)
# Output 20

使用生成器参数通常比首先创建临时列表更有效和更优雅。 例如,如果没有使用生成器表达式,则可以考虑使用此替代实现:

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

这有效,但它引入了额外的步骤并创建了一个额外的列表。 对于小的列表,它可能没关系,但如果nums很大,最终会创建一个大的临时数据结构,只能使用一次并丢弃。 生成器解决方案迭代地转换数据,因此内存效率更高。
min(), max()和sorted()都有一个额外的参数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'])

猜你喜欢

转载自www.cnblogs.com/jeffrey-yang/p/11316549.html
今日推荐