Earlier today I needed to iterate over a string 2 characters at a time for parsing a string formatted like \"+c-R+D-E\"
(there are a few extra letters).
Consider pip
installing more_itertools, which already ships with a chunked implementation along with other helpful tools:
import more_itertools
for op, code in more_itertools.chunked(s, 2):
print(op, code)
Output:
+ c
- R
+ D
- e
I ran into a similar problem. Ended doing something like this:
ops = iter("+c-R+D-e")
for op in ops
code = ops.next()
print op, code
I felt it was the most readable.
Maybe not the most efficient, but if you like regexes...
import re
s = "+c-R+D-e"
for op, code in re.findall('(.)(.)', s):
print op, code
Triptych inspired this more general solution:
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
The other answers work well for n = 2, but for the general case you could try this:
def slicen(s, n, truncate=False):
nslices = len(s) / n
if not truncate and (len(s) % n):
nslices += 1
return (s[i*n:n*(i+1)] for i in range(nslices))
>>> s = '+c-R+D-e'
>>> for op, code in slicen(s, 2):
... print op, code
...
+ c
- R
+ D
- e
>>> for a, b, c in slicen(s, 3):
... print a, b, c
...
+ c -
R + D
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: need more than 2 values to unpack
>>> for a, b, c in slicen(s,3,True):
... print a, b, c
...
+ c -
R + D
Dunno about cleaner, but there's another alternative:
for (op, code) in zip(s[0::2], s[1::2]):
print op, code
A no-copy version:
from itertools import izip, islice
for (op, code) in izip(islice(s, 0, None, 2), islice(s, 1, None, 2)):
print op, code