Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 11, 2008 15:49:27

Zeba
От:
Зарегистрирован: 2008-12-11
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

разбиение строки

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

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

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 решения :)



Офлайн

#2 Дек. 11, 2008 16:53:33

ZAN
От:
Зарегистрирован: 2007-06-10
Сообщения: 403
Репутация: +  10  -
Профиль   Отправить e-mail  

разбиение строки

Офлайн

#3 Дек. 12, 2008 06:21:17

ZZZ
От: Москва
Зарегистрирован: 2008-04-03
Сообщения: 2161
Репутация: +  26  -
Профиль   Адрес электронной почты  

разбиение строки

Скорее всего более правильным решением будет создание генератора, так как этот список будет обрабатываться циклом 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)
ИМХО, второй вариант самый понятный и красивый и поучительный.



Офлайн

#4 Дек. 12, 2008 06:21:23

shiza
От:
Зарегистрирован: 2007-07-03
Сообщения: 1073
Репутация: +  0  -
Профиль   Отправить e-mail  

разбиение строки

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)



Отредактировано (Дек. 12, 2008 06:26:17)

Офлайн

#5 Дек. 12, 2008 06:27:51

ZZZ
От: Москва
Зарегистрирован: 2008-04-03
Сообщения: 2161
Репутация: +  26  -
Профиль   Адрес электронной почты  

разбиение строки

Красиво и офифигительно быстро!

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



Отредактировано (Дек. 12, 2008 06:39:27)

Офлайн

#6 Дек. 12, 2008 09:50:32

Zeba
От:
Зарегистрирован: 2008-12-11
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

разбиение строки

Вариант shiza классный, к чему-то такому шел, но не дошел :)
Спасибо всем за решения!



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version