Apa adalah cara yang efisien untuk mengulang string dengan panjang tertentu? Misalnya: ulangi('abc', 7) -> 'abcabca'
Di sini saya saat ini code:
def repeat(string, length):
cur, old = 1, string
while len(string) < length:
string += old[cur-1]
cur = (cur+1)%len(old)
return string
Apakah ada yang lebih baik (lebih pythonic) cara untuk melakukan ini? Mungkin menggunakan daftar pemahaman?
Jason Scheirer's jawaban benar tetapi bisa menggunakan beberapa lebih eksposisi.
Pertama, untuk mengulang string integer beberapa kali, anda dapat menggunakan kelebihan beban perkalian:
>>> 'abc' * 7
'abcabcabcabcabcabcabc'
Jadi, untuk mengulang string sampai's at least panjang anda ingin, anda menghitung jumlah yang tepat dari mengulangi dan meletakkannya di sisi kanan dari perkalian operator:
def repeat_to_at_least_length(s, wanted):
return s * (wanted//len(s) + 1)
>>> repeat_to_at_least_length('abc', 7)
'abcabcabc'
Kemudian, anda dapat memotongnya dengan panjang yang tepat yang anda inginkan dengan array slice:
def repeat_to_length(s, wanted):
return (s * (wanted//len(s) + 1))[:wanted]
>>> repeat_to_length('abc', 7)
'abcabca'
Atau, seperti yang disarankan di pillmod's jawaban yang mungkin tak seorang pun bergulir ke bawah cukup jauh untuk melihat lagi, anda dapat menggunakan divmod
untuk menghitung jumlah pengulangan yang dibutuhkan, dan jumlah karakter tambahan, semua sekaligus:
def pillmod_repeat_to_length(s, wanted):
a, b = divmod(wanted, len(s))
return s * a + s[:b]
Mana yang lebih baik? Let's benchmark ini:
>>> import timeit
>>> timeit.repeat('scheirer_repeat_to_length("abcdefg", 129)', globals=globals())
[0.3964178159367293, 0.32557755894958973, 0.32851039397064596]
>>> timeit.repeat('pillmod_repeat_to_length("abcdefg", 129)', globals=globals())
[0.5276265419088304, 0.46511475392617285, 0.46291469305288047]
Jadi, pillmod's versi adalah sesuatu seperti 40% lebih lambat, yang terlalu buruk, karena secara pribadi saya pikir itu's jauh lebih mudah dibaca. Ada beberapa kemungkinan alasan untuk ini, dimulai dengan menyusun sekitar 40% lebih instruksi bytecode.
Catatan: contoh-contoh ini menggunakan new-ish //
operator untuk membatasi pembagian integer. Hal ini sering called Python 3 fitur, tapi menurut PEP 238, diperkenalkan kembali di Python 2.2. Anda hanya have untuk menggunakannya di Python 3 (atau pada modul yang telah dari __masa__ impor pembagian
) tapi anda can menggunakannya terlepas.
def repeat_to_length(string_to_expand, length):
return (string_to_expand * ((length/len(string_to_expand))+1))[:length]
Untuk python3:
def repeat_to_length(string_to_expand, length):
return (string_to_expand * (int(length/len(string_to_expand))+1))[:length]
Bagaimana tentang string * (panjang / len(string)) + string[0:(panjang % len(string))]
Mungkin bukan solusi yang paling efisien, tapi jelas singkat & sederhana:
def repstr(string, length):
return (string * length)[0:length]
repstr("foobar", 14)
Memberikan "foobarfoobarfo". Satu hal tentang versi ini adalah bahwa jika panjang < len(string) maka output string yang akan dipotong. Misalnya:
repstr("foobar", 3)
Memberikan "anu".
Edit: benar-benar mengejutkan saya, ini lebih cepat dari yang diterima saat ini larutan ('repeat_to_length' fungsi), setidaknya pada string pendek:
from timeit import Timer
t1 = Timer("repstr('foofoo', 30)", 'from __main__ import repstr')
t2 = Timer("repeat_to_length('foofoo', 30)", 'from __main__ import repeat_to_length')
t1.timeit() # gives ~0.35 secs
t2.timeit() # gives ~0.43 secs
Mungkin jika string yang panjang, atau suhu udara yang sangat tinggi (yaitu, jika pemborosan dari string * panjang
bagian tinggi) maka akan tampil buruk. Dan pada kenyataannya kita dapat memodifikasi atas untuk memverifikasi ini:
from timeit import Timer
t1 = Timer("repstr('foofoo' * 10, 3000)", 'from __main__ import repstr')
t2 = Timer("repeat_to_length('foofoo' * 10, 3000)", 'from __main__ import repeat_to_length')
t1.timeit() # gives ~18.85 secs
t2.timeit() # gives ~1.13 secs
Tidak ada yang ingin't sudah cukup jawaban untuk pertanyaan ini, tetapi ada fungsi ulangi, hanya perlu membuat daftar dan kemudian bergabung dengan output:
from itertools import repeat
def rep(s,n):
''.join(list(repeat(s,n))
Yay rekursi!
def trunc(s,l):
if l > 0:
return s[:l] + trunc(s, l - len(s))
return ''
Won't skala selamanya, tapi itu's baik untuk string yang lebih kecil. Dan itu's cukup.
Saya akui saya hanya membaca Sedikit Siasat dan saya suka rekursi sekarang.
Ini adalah salah satu cara untuk melakukan ini dengan menggunakan daftar pemahaman, meskipun itu's semakin boros panjang rpt
string meningkat.
def repeat(rpt, length):
return ''.join([rpt for x in range(0, (len(rpt) % length))])[:length]