Найти - Пользователи
Полная версия: разбиение строки
Начало » Python для новичков » разбиение строки
1
Zeba
Нужно разбить строку произвольной длины на подстроки одинаковой длины.
Набросал функцию, но терзают сомнения, что есть либо билтин, либо более красивое решение.

Вообщем, присылайте свои версии.
Минусы моего решения: если длина строки кратна длине желаемых подстрок, получаем пустую строку в конце.

def cut(string, n):
parts = len(string)//n
arr = []
for count in xrange(parts):
arr.append(s[n*count:n*count + n])
arr.append(s[n*(count+1):])
return arr
http://dumpz.org/3858/

Хотелось увидеть наиболее pythonic style решения :)
ZAN
textwrap
http://www.python.org/doc/2.5.2/lib/module-textwrap.html
ZZZ
Скорее всего более правильным решением будет создание генератора, так как этот список будет обрабатываться циклом for. Но даже если это и не так, попробуйте выполнить следующий код:
# -*- coding: utf-8 -*-

import timeit

def div_str(string, part_lenght):
for n in xrange(len(string)//part_lenght):
yield string[n * part_lenght : (n+1) * part_lenght]
if string[(n+1) * part_lenght : (n+2) * part_lenght]:
yield string[(n+1) * part_lenght : (n+2) * part_lenght]

print list(div_str("0123456789", 4))
print list(div_str("0123456789", 2))
print timeit.Timer('for _ in div_str("0123456789" * 10000, 30): pass',
'from __main__ import div_str').timeit(1000)
print timeit.Timer('list(div_str("0123456789" * 10000, 30))',
'from __main__ import div_str').timeit(1000)

print '-=-' * 10

def div_str(string, part_lenght):
from cStringIO import StringIO
sio = StringIO(string)
while True:
d = sio.read(part_lenght)
if not d:
return
yield d

print list(div_str("0123456789", 4))
print list(div_str("0123456789", 2))
print timeit.Timer('for _ in div_str("0123456789" * 10000, 30): pass',
'from __main__ import div_str').timeit(1000)
print timeit.Timer('list(div_str("0123456789" * 10000, 30))',
'from __main__ import div_str').timeit(1000)

print '-=-' * 10

from textwrap import wrap
print wrap("0123456789", 4)
print wrap("0123456789", 2)
print timeit.Timer('for _ in wrap("0123456789" * 10000, 30): pass',
'from textwrap import wrap').timeit(1000)
ИМХО, второй вариант самый понятный и красивый и поучительный.
shiza
s = 'Testosterone is a steroid hormone from the androgen group...'
step = 4
print [s[i:i+step] for i in xrange(0, len(s), step)]
или, если через итератор:

s = 'Testosterone is a steroid hormone from the androgen group...'
step = 4
it = (s[i:i+step] for i in xrange(0, len(s), step)])
print list(it)
ZZZ
Красиво и офифигительно быстро!

# -*- coding: utf-8 -*-

import timeit

string = "0123456789" * 10000
step = 30
print timeit.Timer('[string[i:i+step] for i in xrange(0, len(string), step)]',
'from __main__ import string, step').timeit(1000)
print timeit.Timer('for _ in (string[i:i+step] for i in xrange(0, len(string), step)): pass',
'from __main__ import string, step').timeit(1000)
Zeba
Вариант shiza классный, к чему-то такому шел, но не дошел :)
Спасибо всем за решения!
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB