Выполните итерации по строке 2 (или n) символы за один раз в Python

Ошибка синтаксического анализа: синтаксическая ошибка, неожиданный T_PAAMAYIM_NEKUDOTAYIM

Оператор разрешения контекста также называется «Paamayim Nekudotayim» с иврита פעמיים נקודתיים. что означает «двойное двоеточие» или «двойная точка дважды».

Эта ошибка обычно возникает, если вы случайно в коде добавили ::.

Смежные вопросы:

Документация:

32
задан Richard Levasseur 18 June 2011 в 04:09
поделиться

8 ответов

Не знаю, что такое очиститель, но есть другая альтернатива:

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
47
ответ дан 27 November 2019 в 20:13
поделиться

Может быть, это будет чище?

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

Вы могли бы, возможно, написать генератор, чтобы делать то, что вы хотите, может быть, он будет более питоническим :)

13
ответ дан 27 November 2019 в 20:13
поделиться

Триптих вдохновил на это более общее решение:

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
5
ответ дан 27 November 2019 в 20:13
поделиться
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 требует 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)
4
ответ дан 27 November 2019 в 20:13
поделиться

Отличные возможности для генератора. Для больших списков это будет намного эффективнее, чем архивирование всех остальных элементов. Обратите внимание, что эта версия также обрабатывает строки с висячими 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

edit: minor rewrite, чтобы избежать исключений ValueError.

3
ответ дан 27 November 2019 в 20:13
поделиться

Другие ответы работают хорошо для 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
2
ответ дан 27 November 2019 в 20:13
поделиться
>>> s = "+c-R+D-e"
>>> s
'+c-R+D-e'
>>> s[::2]
'+-+-'
>>>
1
ответ дан 27 November 2019 в 20:13
поделиться

Возможно, не самый эффективный, но если хотите регулярные выражения ...

import re
s = "+c-R+D-e"
for op, code in re.findall('(.)(.)', s):
    print op, code
1
ответ дан 27 November 2019 в 20:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: