迭代中的n的倍数巨蟒序列?迭代中的n的倍数巨蟒序列?(Iterate over a python s

2019-05-11 22:07发布

如何处理顺序分批元素,地道?

例如,与序列“ABCDEF”和2的批量大小,我想这样做的以下内容:

for x, y in "abcdef":
    print "%s%s\n" % (x, y)
ab
cd
ef

当然,因为它期待从它本身包含2个元素的列表中的某个元素,这并不工作。

什么是处理列表的批处理从一个更大的字符串(两个类似的问题)接下来的n个元素,或长度为n的子串一个不错的,短的,干净的,Python的方式?

Answer 1:

我肯定有人会拿出一些更“Python化”,但怎么样:

for y in range(0, len(x), 2):
    print "%s%s" % (x[y], x[y+1])

需要注意的是,如果你知道这只会工作是len(x) % 2 == 0;



Answer 2:

发电机的功能是整洁:

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


Answer 3:

我有另一种方法,对于不具有已知长度iterables工作。

   
def groupsgen(seq, size):
    it = iter(seq)
    while True:
        values = ()        
        for n in xrange(size):
            values += (it.next(),)        
        yield values    

它通过遍历在大小的组的序列(或其他迭代器),在元组收集的值。 在每个组的结尾处,它产生元组。

当迭代用完值时,它产生一个StopIteration异常,然后向上传播,表明groupsgen超出值。

它假定值进来集大小(套的2,3等)。 如果没有,剩下的任何值只是被丢弃。



Answer 4:

不要忘记的zip()函数:

a = 'abcdef'
for x,y in zip(a[::2], a[1::2]):
  print '%s%s' % (x,y)


Answer 5:

但更普遍的方式是(灵感来自这个答案 ):

for i in zip(*(seq[i::size] for i in range(size))):
    print(i)                            # tuple of individual values


Answer 6:

然后总是有文档 。

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    try:
        b.next()
    except StopIteration:
        pass
    return izip(a, b)

def grouper(n, iterable, padvalue=None):
    "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
    return izip(*[chain(iterable, repeat(padvalue, n-1))]*n)

注意:这些产生的元组,而不是子,给定一个字符串序列输入时。



Answer 7:

>>> a = "abcdef"
>>> size = 2
>>> [a[x:x+size] for x in range(0, len(a), size)]
['ab', 'cd', 'ef']

..或者,而不是作为一个列表理解:

a = "abcdef"
size = 2
output = []
for x in range(0, len(a), size):
    output.append(a[x:x+size])

或者,如发电机,假若多次使用是最好(对于一个使用的东西,列表理解大概是“最好的”):

def chunker(thelist, segsize):
    for x in range(0, len(thelist), segsize):
            yield thelist[x:x+segsize]

..和它的用法:

>>> for seg in chunker(a, 2):
...     print seg
... 
ab
cd
ef


Answer 8:

您可以创建以下发电机

def chunks(seq, size):
    a = range(0, len(seq), size)
    b = range(size, len(seq) + 1, size)
    for i, j in zip(a, b):
        yield seq[i:j]

并使用它像这样:

for i in chunks('abcdef', 2):
    print(i)


Answer 9:

从more_itertools的文档 : more_itertools.chunked()

more_itertools.chunked(iterable, n)

断裂成可迭代给定长度的列表:

>>> list(chunked([1, 2, 3, 4, 5, 6, 7], 3))
[[1, 2, 3], [4, 5, 6], [7]]

如果迭代的长度不被n整除,最后返回的列表将会缩短。



Answer 10:


s = 'abcdefgh'
for e in (s[i:i+2] for i in range(0,len(s),2)):
  print(e)


Answer 11:

该itertools文档有这个配方:

from itertools import izip_longest

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

用法:

>>> l = [1,2,3,4,5,6,7,8,9]
>>> [z for z in grouper(l, 3)]
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]


Answer 12:

一个解决方案,但我挑战别人做的更好;-)

a = 'abcdef'
b = [[a[i-1], a[i]] for i in range(1, len(a), 2)]

for x, y in b:
  print "%s%s\n" % (x, y)


Answer 13:

如何itertools?

from itertools import islice, groupby

def chunks_islice(seq, size):
    while True:
        aux = list(islice(seq, 0, size))
        if not aux: break
        yield "".join(aux)

def chunks_groupby(seq, size):
    for k, chunk in groupby(enumerate(seq), lambda x: x[0] / size):
        yield "".join([i[1] for i in chunk])


Answer 14:

除了两个答案,我看到了很多批次过早物化和下标(这并不适用于所有的迭代器工作)的。 因此,我想出了这个替代方案:

def iter_x_and_n(iterable, x, n):
    yield x
    try:
        for _ in range(n):
            yield next(iterable)
    except StopIteration:
        pass

def batched(iterable, n):
    if n<1: raise ValueError("Can not create batches of size %d, number must be strictly positive" % n)
    iterable = iter(iterable)
    try:
        for x in iterable:
            yield iter_x_and_n(iterable, x, n-1)
    except StopIteration:
        pass

这可难倒了我,没有这个的一行或几班轮解决方案(尽我knowleged的)。 关键的问题是,无论是外发生器和内部发电机需要正确处理的StopIteration。 如果有剩下的至少一个元素是外部发电机只能产生的东西。 要检查这种直观的方式,为下一待执行(......),赶上一个StopIteration。



Answer 15:

特定

from __future__ import print_function                      # python 2.x

seq = "abcdef"
n = 2

while seq:
    print("{}".format(seq[:n]), end="\n")
    seq = seq[n:]

产量

ab
cd
ef


Answer 16:

这里是一个解决方案,其产生超过n个项的一系列迭代器,其中的每一个迭代的。

def groupiter(thing, n):
    def countiter(nextthing, thingiter, n):
        yield nextthing
        for _ in range(n - 1):
            yield next(thingiter)
    thingiter = iter(thing)
    while True:
        try:
            nextthing = next(thingiter)
        except StopIteration:
            return None
        yield countiter(nextthing, thingiter, n)

我使用它,如下所示:

table = list(range(250))
for group in groupiter(table, 16):
    print(', '.join('0x{:02X}'.format(x) for x in group))

需要注意的是它可以处理不是n的倍数的对象的长度。



文章来源: Iterate over a python sequence in multiples of n?