Разделить строку на N равных частей?
У меня есть строка, которую я хотел бы разбить на N равных частей.
Например, представьте, что у меня была строка длиной 128 и я хочу разбить ее на 4 куска длиной 32 каждый; то есть сначала 32 символа, затем второй 32 и т.д.
Как я могу это сделать?
Ответы
Ответ 1
import textwrap
print textwrap.wrap("123456789", 2)
#prints ['12', '34', '56', '78', '9']
Примечание: будьте осторожны с пробелами и т.д. - это может быть или не быть тем, что вы хотите.
"""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
Вы можете использовать простой цикл:
parts = [your_string[i:i+n] for i in range(0, len(your_string), n)]
Ответ 3
Другой распространенный способ группировки элементов в группы n-длины:
>>> s = '1234567890'
>>> list(map(''.join, zip(*[iter(s)]*2)))
['12', '34', '56', '78', '90']
Этот метод поступает прямо из документов для zip()
.
Ответ 4
Во многих случаях вы можете обрабатывать строку подобно списку. Здесь есть много ответов: Разделение списка на N частей примерно равной длины
например, вы могли бы выработать chunk_size = len(my_string)/N
Затем, чтобы получить доступ к фрагменту, вы можете пойти my_string[i: i + chunk_size]
(а затем увеличивать i
на chunk_size) - либо в цикле for, либо в понимании списка.
Ответ 5
Мне нравятся итераторы!
def chunk(in_string,num_chunks):
chunk_size = len(in_string)//num_chunks
if len(in_string) % num_chunks: chunk_size += 1
iterator = iter(in_string)
for _ in range(num_chunks):
accumulator = list()
for _ in range(chunk_size):
try: accumulator.append(next(iterator))
except StopIteration: break
yield ''.join(accumulator)
## DEMO
>>> string = "a"*32+"b"*32+"c"*32+"d"*32
>>> list(chunk(string,4))
['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', 'cccccccccccccccccccccccccccccccc', 'dddddddddddddddddddddddddddddddd']
>>> string += "e" # so it not evenly divisible
>>> list(chunk(string,4))
['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcc', 'ccccccccccccccccccccccccccccccddd', 'ddddddddddddddddddddddddddddde']
Также явно быстрее, чем textwrap.wrap
, хотя почти наверняка менее "хороший"
>>> timeit.timeit(lambda: list(chunk(string,4)),number=500)
0.047726927170444355
>>> timeit.timeit(lambda: textwrap.wrap(string,len(string)//4),number=500)
0.20812756575945457
И довольно легко взломать работу с любым итерабельным (просто отпустите str.join
и получите накопитель, если isinstance(in_string,str)
)
# after a petty hack
>>> list(chunk([1,2,3,4,5,6,7,8,9,10,11,12],4))
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
Ответ 6
Рекурсивный путь:
def split_str(seq, chunk, skip_tail=False):
lst = []
if chunk <= len(seq):
lst.extend([seq[:chunk]])
lst.extend(split_str(seq[chunk:], chunk, skip_tail))
elif not skip_tail and seq:
lst.extend([seq])
return lst
Демо:
seq = "123456789abcdefghij"
print(split_str(seq, 3))
print(split_str(seq, 3, skip_tail=True))
# ['123', '456', '789', 'abc', 'def', 'ghi', 'j']
# ['123', '456', '789', 'abc', 'def', 'ghi']