2016-02-19 2 views
1

Я знаю метод textwrap.wrap, но этот метод разбивает строку на фиксированную длину для каждой части, но я ищу функцию в python, которая разбивает строку на фиксированное число частей.Как разбить строку на фиксированное количество частей в Python?

Например: string = "Hello, my name is foo"
и foo(string, 7)
возвращает ['Hel', 'lo,', ' my', ' na', 'me ', 'is ', 'foo']

алгоритмический, я знаю, как реализовать этот метод, но я хочу знать, если есть модуль, который обеспечивает его или «волшебную функцию» в regex, который отвечает на эту проблему ...

+0

@Stidgeon я говорил, что я не хочу, метод textwrap.wrap :) – Etgar

+0

Как вы хотите, чтобы это было обработано, когда строка не может быть разделена поровну ? Например, если длина строки равна 9, и вы хотите, чтобы 4 части хотели, чтобы части имели длины [3, 2, 2, 2]? Вы хотите ошибку. Вы хотите, чтобы большая часть была в начале или в конце? –

+0

Проголосовал за повторное открытие, потому что связанный вопрос задавал четные куски, где этот вопрос задает определенное количество кусков. –

ответ

1

Один подход может быть использован re.

import re 
string = "Hello, my name is foo" 
def foo(string, parts): 
    x=len(string)/parts 
    print re.findall(r".{"+str(x)+r"}|.+?$",string) 

foo(string,7) 

Выход: ['Hel', 'lo,', ' my', ' na', 'me ', 'is ', 'foo']

+0

'foo (string, 6)' возвращает тот же результат, что и 'foo (string, 7)'. 'foo (string, 5)' оставляет последнюю букву предложения. (Временное downvote до фиксированного. Извините.) –

+0

@StevenRumbalski исправлено ............. foo (6) и foo (7) будут одинаковыми. У вас могут быть буквы '3.5' – vks

+0

Давая один дополнительный элемент, когда строка не равномерно делится, является неожиданным результатом. Вы можете позвонить в свой ответ. –

0

Я не думаю, что есть встроенный, но я думаю, что вы могли бы сделать это с регулярным выражением: https://stackoverflow.com/a/9477447/1342445

В этом случае ваша функция генерирует регулярное выражение из Len (вход)/int (части) строки и вызывает ошибку, если она не делится на вход. Было бы гораздо проще с неопределенным поведением остаточным :)

Я думаю, что это будет выглядеть примерно так:

import re 


def split_into(string: str, parts: int): 
    if (len(string) % parts) != 0: 
     raise NotImplementedError('string is not divisible by # parts') 

    chunk_size = len(string)/parts 
    regex = '.'*chunk_size 
    return re.findall(regex, string) 
+0

Будучи равномерно делимым, это ограничение, но, по крайней мере, вы это называете. –

+0

Действительно, но ответ становится более нюансным, когда у вас есть остаток. Как вы его распространяете? Размер блока становится динамическим, а не фиксированным и т. Д. – pnovotnak

1

Я не знаю, если какой-либо модуль делает это ..., но я вынужден сказать, что Проблема здесь в основном What is the most "pythonic" way to iterate over a list in chunks?, за исключением того, что у вас есть строки вместо списков. Но, пожалуй, самый питонический путь здесь должен быть самым питоническим, и это хорошо, если вы можете избежать re. Так вот решение (не уверен, что вы хотите, если строка не может быть равномерно разделена на количество частей, если вы просто выбросить «остаток»):

# python 3 version 
def foo(string, n): 
    part_len = -(-len(string) // n) # same as math.ceil(len(string)/n) 
    return [''.join(x) for x in zip(*[iter_str] * part_len)] 

Таким образом:

>>> s = "Hello, my name is foo" 
>>> foo(s, 7) 
['Hel', 'lo,', ' my', ' na', 'me ', 'is ', 'foo'] 
>>> foo(s, 6) 
['Hell', 'o, m', 'y na', 'me i', 's fo'] 

Теперь, по общему признанию, foo(s, 6) возвращает список длины 5, что несколько удивительно. Возможно, вы хотите вместо этого создать исключение. Если вы хотите сохранить остаток, затем использовать zip_longest

from itertools import zip_longest 

def foo2(string, n, pad=''): 
    part_len = -(-len(string) // n) 
    return [''.join(x) for x in zip_longest(*[iter(string)] * part_len, fillvalue=pad)] 

>>> foo2(s, 6) 
['Hell', 'o, m', 'y na', 'me i', 's fo', 'o'] 
>>> foo2(s, 6, pad='?') 
['Hell', 'o, m', 'y na', 'me i', 's fo', 'o???'] 
Смежные вопросы