n 번째 문자마다 문자열을 분할 하시겠습니까?


답변:


549
>>> line = '1234567890'
>>> n = 2
>>> [line[i:i+n] for i in range(0, len(line), n)]
['12', '34', '56', '78', '90']

35
이것은 어떤 식으로도 뒤얽 히지 않았기 때문에 정말 좋은 대답입니다. 그 사실은 단순함으로 인해이 방법을 쉽게 기억할 수있게합니다.
Trevor Rudolph

1
@TrevorRudolph 그것은 당신이 말한 대로만합니다. 위의 답변은 실제로 for 루프 일 뿐이지 만 파이썬으로 표현됩니다. 또한 "단순한"답변을 기억해야 할 경우 적어도 수십만 가지의 방법으로 기억할 수 있습니다. 복사하여 이메일에 붙여 넣기; 당신이 기억하고 싶은 것들과 함께 "유용한"파일을 유지; 무언가가 필요할 때마다 최신 검색 엔진을 사용하기 만하면됩니다. 모든 웹 브라우저에서 (아마도) 북마크를 사용하는 것; 등
dylnmc

1
두 번째로, 그것은 당신 진지한 것처럼 보입니다 . 나는 그것이 실제로 복잡 하지 않기 때문에 당신이 진지하기를 바랍니다 .
dylnmc

1
나는 진지하고 있었고, 에뮬레이터의 이진 변환기 에이 코드를 사용했는데, 그것은 pythonic for loop haaha 인 것이 좋았지 만 왜 메소드를 즐기는 지에 대해 더 분석 해 주셔서 감사합니다!
Trevor Rudolph

5
아이러니하게도, 숨겨진 의미를 갖지 않는 방식으로 단어를 사용하려고하면 종종 복잡한 문장이 나옵니다.
deed02392

207

완료하기 위해 정규식 으로이 작업을 수행 할 수 있습니다.

>>> import re
>>> re.findall('..','1234567890')
['12', '34', '56', '78', '90']

홀수의 문자에 대해 다음을 수행 할 수 있습니다.

>>> import re
>>> re.findall('..?', '123456789')
['12', '34', '56', '78', '9']

긴 청크에 대한 정규식을 단순화하기 위해 다음을 수행 할 수도 있습니다.

>>> import re
>>> re.findall('.{1,2}', '123456789')
['12', '34', '56', '78', '9']

re.finditer문자열이 청크별로 청크를 생성하는 데 긴 경우 사용할 수 있습니다 .


3
이것은 지금까지 가장 좋은 대답이며 최상위에 있어야합니다. '.'*n더 명확하게하기 위해 글 을 쓸 수도 있습니다. 결합 없음, 압축 없음, 루프 없음, 목록 이해력 없음; 서로 옆에있는 다음 두 문자를 찾으십시오. 이것은 인간의 두뇌가 정확히 어떻게 생각하는지입니다. Monty Python이 여전히 살아 있다면 그는이 방법을 좋아할 것입니다!
jdk1.0

이것 역시 합리적으로 긴 문자열을위한 가장 빠른 방법입니다 : gitlab.com/snippets/1908857
랄프 볼튼

문자열에 줄 바꿈이 포함되어 있으면 작동하지 않습니다. 이것은 필요합니다 flags=re.S.
Aran-Fey

아아 .... 정규식 .... 왜 그 XD를 생각하지 않았다
Mr PizzaGuy

146

파이썬에는 이미 내장 함수가 있습니다.

>>> from textwrap import wrap
>>> s = '1234567890'
>>> wrap(s, 2)
['12', '34', '56', '78', '90']

이것이 랩의 docstring이 말하는 것입니다 :

>>> help(wrap)
'''
Help on function wrap in module textwrap:

wrap(text, width=70, **kwargs)
    Wrap a single paragraph of text, returning a list of wrapped lines.

    Reformat the single paragraph in 'text' so it fits in lines of no
    more than 'width' columns, and return a list of wrapped lines.  By
    default, tabs in 'text' are expanded with string.expandtabs(), and
    all other whitespace characters (including newline) are converted to
    space.  See TextWrapper class for available keyword args to customize
    wrapping behaviour.
'''

2
print (wrap ( '12345678', 3))은 문자열을 3 자리 그룹으로 나누지 만 앞뒤로 시작하지는 않습니다. 결과 : [ '123', '456', '78']
19:20에

2
'랩 (wrap)'에 대해 배우는 것이 흥미롭지 만 위에서 요청한 내용을 정확히 수행하지는 않습니다. 문자열을 고정 된 수의 문자로 나누지 않고 텍스트를 표시하는 데 더 중점을 둡니다.
Oren

2
wrap문자열에 공백이 있는지 묻는 메시지를 반환하지 않을 수 있습니다. 예 : wrap('0 1 2 3 4 5', 2)반환 ['0', '1', '2', '3', '4', '5'](요소가
제거됨

3
이것은 실제로 질문에 대답하지만 공백이 있고 분할 문자로 유지하려는 경우 어떻게됩니까? wrap ()은 분리 된 문자 그룹 뒤에 똑바로 떨어지면 공백을 제거합니다
Iron Attorney

1
텍스트를 하이픈으로 분할하려는 경우에는 제대로 작동하지 않습니다 (인수로 제공 한 숫자는 실제로 정확한 문자가 아닌 최대 문자 수이며 하이픈과 공백으로 구분됨).
MrVocabulary

80

요소를 n 길이 그룹으로 그룹화하는 또 다른 일반적인 방법은 다음과 같습니다.

>>> s = '1234567890'
>>> map(''.join, zip(*[iter(s)]*2))
['12', '34', '56', '78', '90']

이 방법은에 대한 문서에서 직접 제공됩니다 zip().


2
[19]에서 : a = "hello world"; list (map ( "".join, zip (* [iter (a)] * 4)))) 결과를 얻습니다 [ 'hell', 'o wo'].
truease.com

16
누군가 zip(*[iter(s)]*2)이해하기 가 까다로워 지면 Python에서 어떻게 zip(*[iter(s)]*n)작동합니까?를 읽으십시오 . .
Grijesh Chauhan

15
이것은 문자의 홀수를 고려하지 않고, 단순히 그 문자를 삭제합니다 : >>> map(''.join, zip(*[iter('01234567')]*5))->['01234']
비요른

3
홀수 개의 문자를 처리하려면 다음 zip()itertools.zip_longest()같이 바꾸십시오 .map(''.join, zip_longest(*[iter(s)]*2, fillvalue=''))
Paulo Freitas

또한 유용한 : docs formaps()
winklerrr

57

itertools 버전보다 짧고 읽기 쉽다고 생각합니다.

def split_by_n(seq, n):
    '''A generator to divide a sequence into chunks of n units.'''
    while seq:
        yield seq[:n]
        seq = seq[n:]

print(list(split_by_n('1234567890', 2)))

7
하지만 실제로는 효율적이지 않습니다 : 문자열에 적용될 때 : 너무 많은 사본
Eric

1
seq가 생성기 인 경우 작동하지 않습니다 . itertools 버전의 용도 입니다. 그 OP가 그것을 요구 한 것은 아니지만 itertool의 버전이 단순하지 않다는 비판은 불공평합니다.
CryingCyclops 2016 년

24

나는이 솔루션을 좋아한다 :

s = '1234567890'
o = []
while s:
    o.append(s[:2])
    s = s[2:]


11

다음에서 grouper()레시피를 사용할 수 있습니다 itertools.

파이썬 2.x :

from itertools import izip_longest    

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

파이썬 3.x :

from itertools import zip_longest

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)

이 함수는 메모리 효율적이며 모든 이터 러블과 작동합니다.


5

다음 코드를 시도하십시오.

from itertools import islice

def split_every(n, iterable):
    i = iter(iterable)
    piece = list(islice(i, n))
    while piece:
        yield piece
        piece = list(islice(i, n))

s = '1234567890'
print list(split_every(2, list(s)))

귀하의 답변이 OP의 요구 사항을 충족하지 못하면 yield ''.join(piece)예상대로 작동 하도록 사용해야 합니다. eval.in/813878
Paulo Freitas

4
>>> from functools import reduce
>>> from operator import add
>>> from itertools import izip
>>> x = iter('1234567890')
>>> [reduce(add, tup) for tup in izip(x, x)]
['12', '34', '56', '78', '90']
>>> x = iter('1234567890')
>>> [reduce(add, tup) for tup in izip(x, x, x)]
['123', '456', '789']

3

이 시도:

s='1234567890'
print([s[idx:idx+2] for idx,val in enumerate(s) if idx%2 == 0])

산출:

['12', '34', '56', '78', '90']

2

항상 그렇듯이 하나의 라이너를 좋아하는 사람들을 위해

n = 2  
line = "this is a line split into n characters"  
line = [line[i * n:i * n+n] for i,blah in enumerate(line[::n])]

Python Fiddle에서 이것을 실행 하면 출력으로 print(line)얻습니다 this is a line split into n characters. 더 나은 퍼팅을 할 수 line = [line[i * n:i * n+n] for i,blah in enumerate(line[::n])]있을까요 : ? 이 문제를 해결하면 좋은 답변입니다 :).
Google 검색의 내용

설명이 ,blah필요한 이유는 무엇입니까? blah알파벳 문자로 바꿀 수 있지만 숫자는 사용할 수 없으며 blah또는 쉼표를 제거 할 수 없습니다 . 내 편집자는 ,: s 다음에 공백을 추가 할 것을 제안합니다 .
toonarmycaptain

enumerateiterables 두 개를 반환하므로 두 위치를 두어야합니다. 그러나 실제로이 경우에는 두 번째 iterable이 필요하지 않습니다.
Daniel F

1
blah밑줄 또는 이중 밑줄을 선호하는 대신 stackoverflow.com/questions/5893163/…
Andy Royal

1

짧은 문자열을위한 간단한 재귀 솔루션 :

def split(s, n):
    if len(s) < n:
        return []
    else:
        return [s[:n]] + split(s[n:], n)

print(split('1234567890', 2))

또는 그런 형태로 :

def split(s, n):
    if len(s) < n:
        return []
    elif len(s) == n:
        return [s]
    else:
        return split(s[:n], n) + split(s[n:], n)

재귀 적 접근 방식에서 일반적인 분할 및 정복 패턴을보다 명확하게 보여줍니다 (실제로이 방법을 수행 할 필요는 없지만)


1

나는 같은 시나리오에 갇혀 있었다.

이것은 나를 위해 일했다

x="1234567890"
n=2
list=[]
for i in range(0,len(x),n):
    list.append(x[i:i+n])
print(list)

산출

['12', '34', '56', '78', '90']

0

more_itertools.sliced전에 언급 되었습니다 . more_itertools라이브러리의 추가 옵션은 다음과 같습니다 .

s = "1234567890"

["".join(c) for c in mit.grouper(2, s)]

["".join(c) for c in mit.chunked(s, 2)]

["".join(c) for c in mit.windowed(s, 2, step=2)]

["".join(c) for c in  mit.split_after(s, lambda x: int(x) % 2 == 0)]

후자의 각 옵션은 다음과 같은 출력을 생성합니다.

['12', '34', '56', '78', '90']

논의 된 옵션에 대한 설명서 : grouper , chunked, windowed,split_after


-1

이것은 간단한 for 루프로 달성 할 수 있습니다.

a = '1234567890a'
result = []

for i in range(0, len(a), 2):
    result.append(a[i : i + 2])
print(result)

출력은 [ '12', '34', '56', '78', '90', 'a']와 같습니다.


2
이 코드는 질문에 대답 할 수 있지만,이 코드가 질문에 응답하는 이유 및 / 또는 방법에 대한 추가 컨텍스트를 제공하면 장기적인 가치가 향상됩니다.
β.εηοιτ.βε

2
이것은 다음과 같은 솔루션입니다. stackoverflow.com/a/59091507/7851470
Georgy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.