如何以n的倍数遍历Python序列?

27 投票
17 回答
22946 浏览
提问于 2025-04-15 11:09

我想知道怎么把一串东西分成小批量来处理,比较简单明了的方法是什么?

比如说,我有一个字符串“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; 的情况下才有效。

撰写回答