Iterate over a string 2 (or n) characters at a time in Python

后端 未结 12 1873
悲哀的现实
悲哀的现实 2020-11-30 07:27

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

相关标签:
12条回答
  • 2020-11-30 07:45

    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
    
    0 讨论(0)
  • 2020-11-30 07:51

    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.

    0 讨论(0)
  • 2020-11-30 07:52

    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
    
    0 讨论(0)
  • 2020-11-30 07:54

    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
    
    0 讨论(0)
  • 2020-11-30 07:55

    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
    
    0 讨论(0)
  • 2020-11-30 07:58

    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
    
    0 讨论(0)
提交回复
热议问题