如何以n的倍数遍历Python序列?
我想知道怎么把一串东西分成小批量来处理,比较简单明了的方法是什么?
比如说,我有一个字符串“abcdef”,我想把它每两位一组地处理,也就是像这样:
for x, y in "abcdef":
print "%s%s\n" % (x, y)
ab
cd
ef
当然,这样做是不行的,因为它期待的是列表中的单个元素,而这个元素本身又包含两个元素。
有没有什么简单、干净、符合Python风格的方法,可以把列表中的下n个元素分批处理,或者从一个更长的字符串中提取长度为n的子字符串(这两个问题其实是类似的)?
17 个回答
15
我有一个替代的方法,可以处理那些长度不确定的可迭代对象。
def groupsgen(seq, size):
it = iter(seq)
while True:
values = ()
for n in xrange(size):
values += (it.next(),)
yield values
这个方法是通过将序列(或者其他可迭代对象)分成一组一组的来处理的,每组的大小是固定的,然后把这些值收集到一个元组里。每组结束时,就会返回这个元组。
当可迭代对象里的值用完了,它会产生一个叫做 StopIteration 的异常,这个异常会向上抛出,表示 groupsgen 已经没有值可以用了。
这个方法假设值是成组出现的,比如每组2个、3个等等。如果不是的话,剩下的值就会被丢掉。
47
一个生成器函数会很不错:
def batch_gen(data, batch_size):
for i in range(0, len(data), batch_size):
yield data[i:i+batch_size]
使用示例:
a = "abcdef"
for i in batch_gen(a, 2): print i
输出结果:
ab
cd
ef
10
我相信会有人给出更“符合Python风格”的写法,不过我想说的是:
for y in range(0, len(x), 2):
print "%s%s" % (x[y], x[y+1])
请注意,这个方法只有在你知道 len(x) % 2 == 0;
的情况下才有效。