在Python 2中,您可以使用
itertools
模块中的
izip
和生成器对象的神奇之处编写自己的函数来简化
dict
记录的值对创建。我从Python 2
itertools
文档中一个同名(尽管功能不同)的
recipe获取了
pairwise()
的想法。
在Python 3中使用这种方法,您只需使用普通的
zip()
,因为它会执行
izip()
在Python 2中的工作,导致后者从
itertools
中删除 - 下面的示例解决了这个问题,并且应该适用于两个版本。
try:
from itertools import izip
except ImportError:
izip = zip
def pairwise(iterable):
"s -> (s0,s1), (s2,s3), (s4, s5), ..."
a = iter(iterable)
return izip(a, a)
可以在文件读取for
循环中像这样使用:
from sys import argv
records = {}
for line in open(argv[1]):
fields = (field.strip() for field in line.split(','))
record = dict(pairwise(fields))
records[record['TSN']] = record
print('Found %d records in the file.' % len(records))
但是,等等,这还不是全部!
你可以创建一个名为grouper()
的通用版本,它对应于一个同名的itertools
配方(该配方位于pairwise()
的正下方):
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 中都有效):
import functools
pairwise = functools.partial(grouper, 2)
后记
除非有非常巨大的字段数,否则你可以创建一个实际的序列来存储行项目对(而不是使用没有len()
的生成器表达式):
fields = tuple(field.strip() for field in line.split(','))
优点在于它允许使用简单的切片来进行分组:
try:
xrange
except NameError:
xrange = range
def grouper(n, sequence):
for i in xrange(0, len(sequence), n):
yield sequence[i:i+n]
pairwise = functools.partial(grouper, 2)
for i, k in zip(_x := iter(mylist), _x): ...
- Alex Just Alexfor i, k in zip(_x := iter(mylist), _x): ...
- undefined