복붙노트

[PYTHON] 파이썬에서 한 번에 문자열 2 (또는 n) 문자를 반복 할 수 있습니다.

PYTHON

파이썬에서 한 번에 문자열 2 (또는 n) 문자를 반복 할 수 있습니다.

오늘 이전에 "+ c-R + D-E"(몇 가지 추가 문자가 있음) 형식의 문자열을 구문 분석하기 위해 한 번에 2 자씩 문자열을 반복해야했습니다.

나는 이것으로 끝냈다. 그것은 효과가있다. 그러나 그것은 추해 보인다. 나는 그것이 명백하지 않다고 느껴졌 기 때문에 그것이 무엇을하고 있었는지에 대해 논평했다. 그것은 거의 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

이 작업을 수행하는 더 나은 / 깨끗한 방법이 있습니까?

해결법

  1. ==============================

    1.Dunno는 청소기를 사용하지만 다른 대안이 있습니다.

    Dunno는 청소기를 사용하지만 다른 대안이 있습니다.

    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
    
  2. ==============================

    2.어쩌면이게 더 깔끔한거야?

    어쩌면이게 더 깔끔한거야?

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

    당신은 아마도 당신이 원하는 것을 할 수있는 발전기를 쓸 수 있습니다, 어쩌면 더 pythonic :)

  3. ==============================

    3.삼부작은이보다 일반적인 해결책에 영감을주었습니다.

    삼부작은이보다 일반적인 해결책에 영감을주었습니다.

    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는 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. ==============================

    5.발전기에 좋은 기회. 큰 목록의 경우 다른 모든 요소를 ​​압축하는 것보다 훨씬 효율적입니다. 이 버전은 또한 매달려있는 작업으로 문자열을 처리합니다.

    발전기에 좋은 기회. 큰 목록의 경우 다른 모든 요소를 ​​압축하는 것보다 훨씬 효율적입니다. 이 버전은 또한 매달려있는 작업으로 문자열을 처리합니다.

    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 예외를 피하기 위해 약간 재 작성하십시오.

  6. ==============================

    6.다른 답변은 n = 2에서 잘 작동하지만 일반적으로 다음과 같이 시도 할 수 있습니다.

    다른 답변은 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
    
  7. ==============================

    7.이 접근법은 결과 당 임의의 수의 요소를 지원하고 느리게 평가되며 입력 iterable은 생성자가 될 수 있습니다 (인덱싱을 시도하지 않음).

    이 접근법은 결과 당 임의의 수의 요소를 지원하고 느리게 평가되며 입력 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
    

    왼쪽에있는 요소는 짧은 목록으로 반환됩니다.

    사용 예 :

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

    8.

    >>> s = "+c-R+D-e"
    >>> s
    '+c-R+D-e'
    >>> s[::2]
    '+-+-'
    >>>
    
  9. ==============================

    9.어쩌면 가장 효율적인 것은 아니지만 정규 표현식을 좋아한다면 ...

    어쩌면 가장 효율적인 것은 아니지만 정규 표현식을 좋아한다면 ...

    import re
    s = "+c-R+D-e"
    for op, code in re.findall('(.)(.)', s):
        print op, code
    
  10. ==============================

    10.비슷한 문제가 발생했습니다. 다음과 같이 끝냈습니다.

    비슷한 문제가 발생했습니다. 다음과 같이 끝냈습니다.

    ops = iter("+c-R+D-e")
    for op in ops
        code = ops.next()
    
        print op, code
    

    나는 그것이 가장 가독하다고 느꼈다.

  11. ==============================

    11.내 대답은, 내 눈을 좀 더 깨끗하게한다.

    내 대답은, 내 눈을 좀 더 깨끗하게한다.

    for i in range(0, len(string) - 1):
        if i % 2 == 0:
            print string[i:i+2]
    
  12. ==============================

    12.다른 유용한 도구와 함께 청크 된 구현물과 함께 제공되는 more_itertools를 pip에 설치하는 것을 고려하십시오.

    다른 유용한 도구와 함께 청크 된 구현물과 함께 제공되는 more_itertools를 pip에 설치하는 것을 고려하십시오.

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

    산출:

    + c
    - R
    + D
    - e
    
  13. from https://stackoverflow.com/questions/1162592/iterate-over-a-string-2-or-n-characters-at-a-time-in-python by cc-by-sa and MIT license