在Python中,每次迭代字符串2(或n)个字符
今天早些时候,我需要一次迭代一个字符串2个字符,以便解析一个格式类似在Python中,每次迭代字符串2(或n)个字符,python,iteration,Python,Iteration,今天早些时候,我需要一次迭代一个字符串2个字符,以便解析一个格式类似“+c-R+D-E”(还有几个额外的字母)的字符串 我最终得到了这个,这很有效,但看起来很难看。我最后评论了它在做什么,因为它感觉不明显。这几乎像是蟒蛇,但不完全是 # 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"
“+c-R+D-E”
(还有几个额外的字母)的字符串
我最终得到了这个,这很有效,但看起来很难看。我最后评论了它在做什么,因为它感觉不明显。这几乎像是蟒蛇,但不完全是
# 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
有更好/更干净的方法吗?也许这样更干净
>>> s = "+c-R+D-e"
>>> s
'+c-R+D-e'
>>> s[::2]
'+-+-'
>>>
s = "+c-R+D-e"
for i in xrange(0, len(s), 2):
op, code = s[i:i+2]
print op, code
你也许可以写一个生成器来做你想做的事情,也许那会更像python:)
izip_longest
需要Python 2.6(或更高版本)。如果在Python 2.4或2.5上,请使用中的izip_longest
的定义,或将grouper函数更改为:
from itertools import izip, chain, repeat
def grouper(iterable, n, padvalue=None):
return izip(*[chain(iterable, repeat(padvalue, n-1))]*n)
我不知道清洁剂,但还有另一种选择:
for (op, code) in zip(s[0::2], s[1::2]):
print op, code
无副本版本:
from itertools import izip, islice
for (op, code) in izip(islice(s, 0, None, 2), islice(s, 1, None, 2)):
print op, code
其他答案对于n=2很有效,但对于一般情况,您可以尝试以下方法:
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
def切片n(s,n,truncate=False):
n许可证=len(s)/n
如果未截断和(长度%n):
n许可证+=1
范围内i的返回(s[i*n:n*(i+1)](n许可证))
>>>s='+c-R+D-e'
>>>对于op,切片中的代码(s,2):
... 打印操作,代码
...
+c
-R
+D
-e
>>>对于切片中的a、b、c(s、3):
... 打印a、b、c
...
+c-
研发
回溯(最近一次呼叫最后一次):
文件“”,第1行,是否在中?
ValueError:需要2个以上的值才能解包
>>>对于切片中的a、b、c(s、3、True):
... 打印a、b、c
...
+c-
研发
对于发电机来说,这是一个绝佳的机会。对于较大的列表,这将比压缩其他元素更有效。请注意,此版本还处理悬挂op
s的字符串
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
编辑:轻微重写以避免ValueError异常。启发了这一更通用的解决方案:
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
也许不是最有效的,但是如果你喜欢正则表达式
import re
s = "+c-R+D-e"
for op, code in re.findall('(.)(.)', s):
print op, code
此方法支持每个结果的任意数量的元素,计算是惰性的,输入iterable可以是生成器(不尝试索引): 任何剩余的元素都会在较短的列表中返回 用法示例:
for g in groups_of_n(4, xrange(21)):
print list(g)
[0, 1, 2, 3]
[4, 5, 6, 7]
[8, 9, 10, 11]
[12, 13, 14, 15]
[16, 17, 18, 19]
[20]
我遇到了类似的问题。最后做了这样的事情:
ops = iter("+c-R+D-e")
for op in ops
code = ops.next()
print op, code
我觉得这是最具可读性的。以下是我的答案,对我的眼睛来说稍微干净一点: 范围(0,len(string)-1)中的i的
:
如果i%2==0:
打印字符串[i:i+2]
请考虑安装pip
安装,它已经随实现和其他有用工具一起提供:
import more_itertools
for op, code in more_itertools.chunked(s, 2):
print(op, code)
输出:
+ c
- R
+ D
- e
@Richard,可能在第2行遗漏了a“)”?可能重复+1简单,并且它适用于任意n(如果在len(s)不是n的倍数时处理ValueError异常。少数边缘情况-始终引发ValueError:尝试操作码(“a1”)我真的很喜欢这一个…我只是希望它不要复制以进行迭代。如果字符串的字符数为奇数,zip方法将跳过最后一个字符。最佳答案,除了它重命名为
zip\u longest
range
也支持一个步骤;)--对于范围内的I(0,len(str),2):打印str[I:I+2]
import more_itertools
for op, code in more_itertools.chunked(s, 2):
print(op, code)
+ c
- R
+ D
- e