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

Возможный дубликат:
Каков самый «питонический» способ перебора списка в кусках?

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

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

'1234567890' 

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

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

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

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

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

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

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

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

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

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

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

Вот мое решение:

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

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

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

Используйте itertools . Раздел «Рецепты» руководства предоставляет функцию, которая выполняет именно это:

 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) 

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

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

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

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

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

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

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

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

 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 – длина последнего элемента списка

Вот еще одно решение для более общего случая, когда куски не имеют одинаковой длины. Если длина равна 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);