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

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

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

'1234567890'

Как мне сделать так, чтобы это выглядело так:

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

Ответ 1

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

Ответ 2

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

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

Для этого в 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.
'''

Ответ 4

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

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

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

Используя more-itertools из PyPI:

>>> from more_itertools import sliced
>>> list(sliced('1234567890', 2))
['12', '34', '56', '78', '90']

Ответ 8

Использование лямбда:

split_string = lambda x, n: [x[i:i+n] for i in range(0, len(x), n)]

s = '1234567890'
split_string(s,2)
['12', '34', '56', '78', '90']

Ответ 9

Вы можете использовать рецепт itertools 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)

Эти функции экономят память и работают с любыми итерациями.

Ответ 10

Здесь мое решение:

def split_every(n, s):
    return [ s[i:i+n] for i in xrange(0, len(s), n) ]

print split_every(2, "1234567890")

Ответ 11

Попробуйте использовать следующий код:

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

Ответ 12

>>> 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']

Ответ 13

Попробуй это:

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

Выход:

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

Ответ 14

Как всегда, для тех, кто любит один лайнер

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

Ответ 15

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

Ответ 16

У меня есть этот код, который я использую всякий раз, когда мне нужно это делать:

def split_string(n, st):
    lst = [""]
    for i in str(st):
        l = len(lst) - 1
        if len(lst[l]) < n: 
            lst[l] += i
        else:
            lst += [i]
    return lst

print(split_string(3, "test_string."))

Где:

  • n - длина каждого элемента списка
  • st - это строка, которую нужно разделить
  • lst - это версия списка st
  • i - текущий символ, используемый в st
  • l - это длина последнего элемента списка

Ответ 17

Простое рекурсивное решение для короткой строки:

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)

который более подробно иллюстрирует типичную модель "разделяй и властвуй" в рекурсивном подходе (хотя практически нет необходимости делать это таким образом)

Ответ 18

Одна возможность - использовать регулярные выражения:

import re
re.findall("\w{3}", your_string)

Ответ 19

Spooky one – попытался придумать еще один ответ:

def split(s, chunk_size):
    a = zip(*[s[i::chunk_size] for i in range(chunk_size)])
    return [''.join(t) for t in a]

print(split('1234567890', 1))
print(split('1234567890', 2))
print(split('1234567890', 3))

Выход

['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
['12', '34', '56', '78', '90']
['123', '456', '789']

Ответ 20

def split(s, n):
  """
  Split string every nth character

  Parameters
  ----------
  s: string
  n: value of nth
  """
  new_list = []
  for i in range(0, len(s), n):
    new_list.append(s[i:i+n])
  return new_list

print(split('1234567890', 2))

Ответ 21

Я знаю, что этот вопрос старый, но это самый короткий способ сделать это. Я знаю:

def split_every_n(S, n):
  return [S[i*n:(i+1)*n] for i in range(len(S) / n)]

Это, однако, предполагает, что длина вашей строки кратно n. В противном случае вам придется проложить его.

Ответ 22

Это может быть немного яснее

##Define your string
mystring = '1234567890'

##Define your starting index
start = 0
##Define the end of your index for the first slice
end = 2

##Create an empty list
mylist =[]

##While the slice of characters without white space has something in it keep going
while len(mystring[start:end])>0:
    ##Add to the list
    mylist.append(mystring[start:end])
    ##Move the index up for the begining and ending of the slice
    start+=2
    end+=2

Ответ 23

def splitstr(oldstr,n):
    start = 0
    end = n
    newlist =[]
    while len(oldstr[start:end])>0:
        newlist.append(oldstr[start:end])
        start+=n
        end+=n
    return newlist
print(splitstr('1234567890', 2))

Ответ 24

Вот еще одно решение для более общего случая, когда куски не имеют одинаковой длины. Если длина равна 0, возвращается вся оставшаяся часть.

data - последовательность, подлежащая разделению; fieldsize - это кортеж со списком длины поля.

def fieldsplit(data=None, fieldsize=()):
    tmpl=[];
    for pp in fieldsize:
        if(pp>0):
            tmpl.append(line[:pp]);
            line=line[pp:];
        else:
            tmpl.append(line);
            break;
    return tuple(tmpl);

Ответ 25

Я использую это:

list(''.join(s) for s in zip(my_str[::2], my_str[1::2]))

или вы можете использовать любой другой n номер вместо 2.

Ответ 26

Функция для отображения группы строк

def display(list):
    for i in list:   #To display the strings
        print(i)
#Take a group of strings from keyboard
print('Enter strings separated by comma: ')
list = [x for x in input().split(",")]

#call display() and pass the list
display(list)

#output
karthik, siva, raman, inban
Enter strings separated by comma: 
karthik
siva
raman
inban

Ответ 27

Этот вопрос напоминает мне метод Perl 6 .comb(n). Он разбивает строки на n -sized кусков. (Там больше, чем это, но я опущу детали.)

Достаточно просто реализовать похожую функцию в Python3 в качестве лямбда-выражения:

comb = lambda s,n: [s[i:i+n] for i in range(0,len(s),n)]

Тогда вы можете назвать это так:

comb('1234567', 2)   # returns ['12', '34', '56', '7']

Эта функция comb() также будет работать со списками (для создания списка списков):

comb(['cat', 'dog', 'bird'], 2)  # returns [['cat', 'dog'], ['bird']]