Разделить строку на каждый n-й символ? - PullRequest
318 голосов
/ 28 февраля 2012

Можно ли разбить строку питона на каждый n-й символ?

Например, предположим, у меня есть строка, содержащая следующее:

'1234567890'

Как мне заставить его выглядеть так:

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

Ответы [ 23 ]

471 голосов
/ 28 февраля 2012
>>> line = '1234567890'
>>> n = 2
>>> [line[i:i+n] for i in range(0, len(line), n)]
['12', '34', '56', '78', '90']
175 голосов
/ 28 февраля 2012

Просто чтобы завершить, вы можете сделать это с помощью регулярного выражения:

>>> 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, если строка длинная для генерации фрагмента по фрагменту.

74 голосов
/ 28 февраля 2012

Еще один распространенный способ группировки элементов в группы n-длины:

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

Этот метод взят прямо из документации для zip().

73 голосов
/ 19 февраля 2018

Для этого в Python уже есть встроенная функция.

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

Вот что говорит строка документации для переноса:

>>> 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.
'''
52 голосов
/ 28 февраля 2012

Я думаю, что это короче и более читабельно, чем версия 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)))
21 голосов
/ 13 сентября 2015

Мне нравится это решение:

s = '1234567890'
o = []
while s:
    o.append(s[:2])
    s = s[2:]
18 голосов
/ 22 июня 2017

Использование more-itertools из PyPI:

>>> from more_itertools import sliced
>>> list(sliced('1234567890', 2))
['12', '34', '56', '78', '90']
11 голосов
/ 03 октября 2015

Вы можете использовать рецепт grouper() из itertools:

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

Python 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 голосов
/ 10 июля 2018

Попробуйте:

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

Вывод:

['12', '34', '56', '78', '90']
4 голосов
/ 28 февраля 2012
>>> 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']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...