स्ट्रिंग को निश्चित लंबाई तक दोहराएं


204

एक स्ट्रिंग को एक निश्चित लंबाई तक दोहराने का एक कुशल तरीका क्या है? उदाहरण के लिए:repeat('abc', 7) -> 'abcabca'

यहाँ मेरा वर्तमान कोड है:

def repeat(string, length):
    cur, old = 1, string
    while len(string) < length:
        string += old[cur-1]
        cur = (cur+1)%len(old)
    return string

क्या ऐसा करने का एक बेहतर (अधिक पायथोनिक) तरीका है? शायद सूची समझ का उपयोग कर?

जवाबों:


73
def repeat_to_length(string_to_expand, length):
   return (string_to_expand * ((length/len(string_to_expand))+1))[:length]

अजगर 3 के लिए:

def repeat_to_length(string_to_expand, length):
    return (string_to_expand * (int(length/len(string_to_expand))+1))[:length]

5
ऐसा लगता है कि यह पूर्णांक विभाजन का लाभ उठा रहा है। क्या //पायथन 3 में होना आवश्यक नहीं है ? या +1छत समारोह के लिए एक स्पष्ट कॉल का उपयोग करना और छोड़ना पर्याप्त होगा। इसके अलावा, एक नोट: उत्पन्न स्ट्रिंग वास्तव में एक अतिरिक्त पुनरावृत्ति होती है जब यह समान रूप से विभाजित होती है; अतिरिक्त बंटवारे से कट जाता है। इसने मुझे पहले उलझन में डाल दिया।
jpmc26

int()यहाँ एक ही बात करता है, लेकिन हाँ, //सूक्ष्म रूप से तेज हो सकता है, क्योंकि यह दो के बजाय एक कमांड में विभाजित और फर्श करता है।
Doyousketch2

667

जेसन शहीर का जवाब सही है लेकिन कुछ और एक्सपोज़र का उपयोग कर सकता है।

सबसे पहले, एक स्ट्रिंग को एक पूर्णांक संख्या को दोहराने के लिए, आप ओवरलोड किए गए गुणन का उपयोग कर सकते हैं:

>>> 'abc' * 7
'abcabcabcabcabcabcabc'

इसलिए, एक स्ट्रिंग को दोहराने के लिए जब तक वह कम से कम जब तक आप चाहते हैं, तब तक आप दोहराए जाने वाले उचित संख्या की गणना करते हैं और इसे उस गुणन ऑपरेटर के दाईं ओर डालते हैं:

def repeat_to_at_least_length(s, wanted):
    return s * (wanted//len(s) + 1)

>>> repeat_to_at_least_length('abc', 7)
'abcabcabc'

फिर, आप इसे सटीक लंबाई के साथ ट्रिम कर सकते हैं जिसे आप ऐरे स्लाइस के साथ चाहते हैं:

def repeat_to_length(s, wanted):
    return (s * (wanted//len(s) + 1))[:wanted]

>>> repeat_to_length('abc', 7)
'abcabca'

वैकल्पिक रूप से, जैसा कि पिल्मॉड के उत्तर में सुझाया गया है कि शायद कोई भी अब तक नोटिस करने के लिए पर्याप्त स्क्रॉल नहीं करता है, आप सभी divmodआवश्यक पुनरावृत्ति की संख्या और अतिरिक्त वर्णों की संख्या की गणना करने के लिए उपयोग कर सकते हैं :

def pillmod_repeat_to_length(s, wanted):
    a, b = divmod(wanted, len(s))
    return s * a + s[:b]

कौनसा अच्छा है? आइए इसे बेंचमार्क करें:

>>> 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]

तो, पिल्मॉड का संस्करण 40% धीमा जैसा कुछ है, जो बहुत बुरा है, क्योंकि व्यक्तिगत रूप से मुझे लगता है कि यह बहुत अधिक पठनीय है। इसके कई संभावित कारण हैं, इसकी शुरुआत लगभग 40% अधिक बायोटेक निर्देशों के संकलन से हुई है।

नोट: ये उदाहरण //पूर्णांक विभाजन को छोटा करने के लिए नए- ish ऑपरेटर का उपयोग करते हैं । इसे अक्सर पायथन 3 फीचर कहा जाता है, लेकिन PEP 238 के अनुसार , इसे Python 2.2 में वापस लाया गया। आप केवल है अजगर 3 में (या मॉड्यूल है कि में इसका उपयोग करना from __future__ import division), लेकिन आप कर सकते हैं यह परवाह किए बिना उपयोग करें।


8
नहीं, ओपी चाहता है कि परिणाम 7 की लंबाई का हो (जो कि 3 का गुणज न हो)।
IANS

1
मैं थोड़ा विवादित हूँ क्योंकि यह ओपी के लिए सही उत्तर नहीं है, लेकिन मेरे और 489 अन्य लोगों के लिए सही उत्तर है ...
मैट फ्लेचर

2
@MattFletcher आपने मुझे "मैं इसे फिर से
लिखूंगा



14
from itertools import cycle, islice
def srepeat(string, n):
   return ''.join(islice(cycle(string), n))

यह वह चीज है जिसका मैं उपयोग करता हूं जब मुझे केवल स्ट्रिंग पर पुनरावृति करने की आवश्यकता होती है (तब सम्मिलित होने की आवश्यकता नहीं होती है)। अजगर पुस्तकालयों को काम करने दें।
विह्लके

7

शायद सबसे कुशल समाधान नहीं है, लेकिन निश्चित रूप से कम और सरल:

def repstr(string, length):
    return (string * length)[0:length]

repstr("foobar", 14)

"फोबारोफोबारोफो" देता है। इस संस्करण के बारे में एक बात यह है कि यदि लंबाई <लेन (स्ट्रिंग) है तो आउटपुट स्ट्रिंग को छोटा कर दिया जाएगा। उदाहरण के लिए:

repstr("foobar", 3)

"फू" देता है।

संपादित करें: वास्तव में मेरे आश्चर्य के लिए, यह वर्तमान में स्वीकृत समाधान ('repeat_to_length' फ़ंक्शन) की तुलना में तेज़ है, कम से कम छोटे तारों पर:

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

संभवत: यदि स्ट्रिंग लंबी थी, या लंबाई बहुत अधिक थी (अर्थात, यदि string * lengthभाग का अपशिष्ट अधिक था) तो यह खराब प्रदर्शन करेगा। और वास्तव में हम इसे सत्यापित करने के लिए उपरोक्त को संशोधित कर सकते हैं:

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

1
आप अधिकतम अनुकूलन के लिए इनपुट और आउटपुट लंबाई के आधार पर दो संस्करणों के बीच एक स्विच जोड़ सकते हैं।
मैड फिजिसिस्ट

6

कैसा रहेगा string * (length / len(string)) + string[0:(length % len(string))]


length / len(string)कोष्ठक में रैपर होने की जरूरत है, और आप आखिरी याद कर रहे हैं ]
माइकवाट

1
मेरी राय में, अब तक का सबसे पठनीय / सहज। मुझे लगता है कि आपको //पाइथन 3 में पूर्णांक विभाजन के लिए उपयोग करने की आवश्यकता 0है। ब्याह में वैकल्पिक है। (बृहदान्त्र आवश्यक है, निश्चित रूप से।)
jpmc26

6

मैं इसका उपयोग करता हूं:

def extend_string(s, l):
    return (s*l)[:l]

5

ऐसा नहीं है कि इस प्रश्न के पर्याप्त उत्तर नहीं हैं, लेकिन एक दोहराव समारोह है; बस एक सूची बनाने और फिर आउटपुट से जुड़ने की आवश्यकता है:

from itertools import repeat

def rep(s,n):
  ''.join(list(repeat(s,n))

इस सवाल का जवाब नहीं है। यह एक स्ट्रिंग X को दोहराता है, इसे X लंबाई तक दोहराता नहीं है। जैसे "abc", 4की उम्मीद होगी "abca"। यह बनाएगाabcabcabcabc
मार्कस लिंड

3

याय पुनरावृत्ति!

def trunc(s,l):
    if l > 0:
        return s[:l] + trunc(s, l - len(s))
    return ''

हमेशा के लिए पैमाना नहीं होगा, लेकिन यह छोटे तारों के लिए ठीक है। और यह सुंदर है।

मैं मानता हूं कि मैं अभी लिटिल स्कीमर को पढ़ता हूं और मुझे अभी पुनरावृत्ति पसंद है।


1

यह एक सूची समझ का उपयोग करने का एक तरीका है, हालांकि यह तेजी से बेकार है क्योंकि rptस्ट्रिंग की लंबाई बढ़ जाती है।

def repeat(rpt, length):
    return ''.join([rpt for x in range(0, (len(rpt) % length))])[:length]


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.