在Python中一次迭代字符串2(或n)个字符

Ric*_*eur 32 python iteration

今天早些时候,我需要一次迭代一个字符串2个字符来解析格式化的字符串"+c-R+D-E"(有一些额外的字母).

我最终得到了这个,但它看起来很难看.我最后评论它正在做什么,因为它感觉不明显.它几乎似乎是pythonic,但并不完全.

# Might not be exact, but you get the idea, use the step
# parameter of range() and slicing to grab 2 chars at a time
s = "+c-R+D-e"
for op, code in (s[i:i+2] for i in range(0, len(s), 2)):
  print op, code
Run Code Online (Sandbox Code Playgroud)

有没有更好/更清洁的方法来做到这一点?

Pav*_*aev 47

Dunno关于清洁,但还有另一种选择:

for (op, code) in zip(s[0::2], s[1::2]):
    print op, code
Run Code Online (Sandbox Code Playgroud)

无副本版本:

from itertools import izip, islice
for (op, code) in izip(islice(s, 0, None, 2), islice(s, 1, None, 2)):
    print op, code
Run Code Online (Sandbox Code Playgroud)


Pag*_*gas 13

也许这会更干净?

s = "+c-R+D-e"
for i in xrange(0, len(s), 2):
    op, code = s[i:i+2]
    print op, code
Run Code Online (Sandbox Code Playgroud)

你也许可以写一个发电机来做你想做的事,也许那会更加pythonic :)


sun*_*ang 6

from itertools import izip_longest
def grouper(iterable, n, fillvalue=None):
    args = [iter(iterable)] * n
    return izip_longest(*args, fillvalue=fillvalue)
def main():
    s = "+c-R+D-e"
    for item in grouper(s, 2):
        print ' '.join(item)
if __name__ == "__main__":
    main()
##output
##+ c
##- R
##+ D
##- e
Run Code Online (Sandbox Code Playgroud)

izip_longest需要 Python 2.6(或更高版本)。如果关于Python 2.4或2.5,则使用定义为izip_longest文件或改变石斑鱼功能:

from itertools import izip, chain, repeat
def grouper(iterable, n, padvalue=None):
    return izip(*[chain(iterable, repeat(padvalue, n-1))]*n)
Run Code Online (Sandbox Code Playgroud)

  • 最佳答案,除了它重命名为 `zip_longest` [在 Python3 中](https://docs.python.org/3.4/library/itertools.html#itertools.zip_longest)。 (2认同)

Tri*_*ych 5

发电机的绝佳机会。对于较大的列表,这将比压缩所有其他元素更有效。请注意,此版本还处理带有悬垂ops的字符串

def opcodes(s):
    while True:
        try:
            op   = s[0]
            code = s[1]
            s    = s[2:]
        except IndexError:
            return
        yield op,code        


for op,code in opcodes("+c-R+D-e"):
   print op,code
Run Code Online (Sandbox Code Playgroud)

编辑:轻微重写以避免 ValueError 异常。


mha*_*wke 5

Triptych启发了这个更通用的解决方案:

def slicen(s, n, truncate=False):
    assert n > 0
    while len(s) >= n:
        yield s[:n]
        s = s[n:]
    if len(s) and not truncate:
        yield s

for op, code in slicen("+c-R+D-e", 2):
    print op,code
Run Code Online (Sandbox Code Playgroud)