python字符串迭代_在Python中一次迭代一個字符串2(或n)個字符

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).

今天早些時候我需要一次迭代一個字符串2個字符來解析格式化為“+ c-R + D-E”的字​​符串(還有一些額外的字母)。

I ended up with this, which works, but it looks ugly. I ended up commenting what it was doing because it felt non-obvious. It almost seems pythonic, but not quite.

我最終得到了這個,但它看起來很難看。我最后評論它正在做什么,因為它感覺不明顯。它幾乎似乎是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

Are there some better/cleaner ways to do this?

有沒有更好/更清潔的方法來做到這一點?

12 个解决方案

#1

40

Dunno about cleaner, but there's another alternative:

Dunno關於清潔,但還有另一種選擇:

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

#2

13

Maybe this would be cleaner?

也許這會更干凈?

s = "+c-R+D-e"

for i in xrange(0, len(s), 2):

op, code = s[i:i+2]

print op, code

You could perhaps write a generator to do what you want, maybe that would be more pythonic :)

你也許可以寫一個發電機來做你想做的事,也許那會更加pythonic :)

#3

4

Triptych inspired this more general solution:

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

#4

4

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

izip_longest requires Python 2.6( or higher). If on Python 2.4 or 2.5, use the definition for izip_longest from the document or change the grouper function to:

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)

#5

2

The other answers work well for n = 2, but for the general case you could try this:

其他答案適用於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 "", 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

#6

2

Great opportunity for a generator. For larger lists, this will be much more efficient than zipping every other elemnent. Note that this version also handles strings with dangling 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

edit: minor rewrite to avoid ValueError exceptions.

編輯:次要重寫以避免ValueError異常。

#7

2

This approach support an arbitrary number of elements per result, evaluates lazily, and the input iterable can be a generator (no indexing is attempted):

這種方法每個結果支持任意數量的元素,懶惰地評估,輸入iterable可以是生成器(不嘗試索引):

import itertools

def groups_of_n(n, iterable):

c = itertools.count()

for _, gen in itertools.groupby(iterable, lambda x: c.next() / n):

yield gen

Any left-over elements are returned in a shorter list.

任何遺留元素都會在較短的列表中返回。

Example usage:

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]

#8

1

>>> s = "+c-R+D-e"

>>> s

'+c-R+D-e'

>>> s[::2]

'+-+-'

>>>

#9

1

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

#10

0

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.

我覺得這是最可讀的。

#11

0

Here's my answer, a little bit cleaner to my eyes:

這是我的答案,我的眼睛有點清潔:

for i in range(0, len(string) - 1):

if i % 2 == 0:

print string[i:i+2]

#12

0

Consider pip installing more_itertools, which already ships with a chunked implementation along with other helpful tools:

考慮使用pip安裝more_itertools,它已經附帶了一個分塊實現以及其他有用的工具:

import more_itertools

for op, code in more_itertools.chunked(s, 2):

print(op, code)

Output:

+ c

- R

+ D

- e

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值