如果我们要将它抽象成函数,那么“从头开始”写起来并不困难:
def pairs(iterable): iterator = iter(iterable) while True: try: yield (iterator.next(), iterator.next()) except: return
不过,罗伯特的配方版绝对可以获得灵活性。
在Python 2中你可以使用 izip 在里面 itertools 模块和生成器对象的魔力来编写自己的函数来简化对值的创建 dict 记录。我明白了 pairwise() 来自同样命名(但功能不同) 食谱 在Python 2中 itertools 文档。
izip
itertools
dict
pairwise()
要在Python 3中使用该方法,您可以使用plain zip() 因为它做了什么 izip() 在Python 2中做了导致后者被删除 itertools 以下示例解决了这个问题,并且应该在两个版本中都有效。
zip()
izip()
try: from itertools import izip except ImportError: # Python 3 izip = zip def pairwise(iterable): "s -> (s0,s1), (s2,s3), (s4, s5), ..." a = iter(iterable) return izip(a, a)
在您的文件阅读中可以使用这个 for 环:
for
from sys import argv records = {} for line in open(argv[1]): fields = (field.strip() for field in line.split(',')) # generator expr record = dict(pairwise(fields)) records[record['TSN']] = record print('Found %d records in the file.' % len(records))
的 但等等,还有更多! 强>
可以创建一个我将调用的通用版本 grouper() ,它再次对应于一个类似命名,但在功能上不同 itertools 食谱(列在右下方 pairwise() ):
grouper()
def grouper(n, iterable): "s -> (s0,s1,...sn-1), (sn,sn+1,...s2n-1), (s2n,s2n+1,...s3n-1), ..." return izip(*[iter(iterable)]*n)
哪个可以在你的中使用 for 环:
record = dict(grouper(2, fields))
当然,对于这样的特定情况,它很容易使用 functools.partial() 并创建一个类似的 pairwise() 使用它的功能(可以在Python 2和3中使用):
functools.partial()
import functools pairwise = functools.partial(grouper, 2)
的 后记 强>
除非有非常多的字段,否则你可以在行对项中创建一个实际的序列(而不是使用没有的生成器表达式) len() ):
len()
fields = tuple(field.strip() for field in line.split(','))
这样做的好处是可以使用简单的切片完成分组:
try: xrange except NameError: # Python 3 xrange = range def grouper(n, sequence): for i in xrange(0, len(sequence), n): yield sequence[i:i+n] pairwise = functools.partial(grouper, 2)
没有那么好 更高效...
完整的解释
import itertools def grouper(n, iterable, fillvalue=None): "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" args = [iter(iterable)] * n return itertools.izip_longest(fillvalue=fillvalue, *args) record = dict(grouper(2, line.strip().split(","))
资源