मेरे पास एक पायथन विधि है जो फॉर्म (स्ट्रिंग, फ्लोट) के टुपल्स की एक सूची लेती है और स्ट्रिंग्स की एक सूची लौटाती है, यदि संयुक्त हो, तो एक निश्चित सीमा से अधिक नहीं होगी। मैं आउटपुट लंबाई को संरक्षित करने के लिए वाक्यों को विभाजित नहीं कर रहा हूं, लेकिन वांछित आउटपुट लंबाई से वाक्य की लंबाई के भीतर रहना सुनिश्चित कर रहा हूं।

उदाहरण के लिए:
एस: [('Where are you',1),('What about the next day',2),('When is the next event',3)]

Max_length : 5
आउटपुट: 'Where are you What about the next day'

Max_length : 3
आउटपुट: 'Where are you'

मैं यही कर रहा हूं:

l=0
output = []
for s in s_tuples:
   if l <= max_length:
     output.append(s[0])
     l+=len(get_words_from(s[0]))
 return ''.join(output)

क्या यह सुनिश्चित करने का कोई बेहतर तरीका है कि आउटपुट शब्द की लंबाई लंबाई तक पहुँचने पर रुकने के अलावा max_length से अधिक न हो?

2
atlantis 9 नवम्बर 2011, 00:23

5 जवाब

सबसे बढ़िया उत्तर

एक बेहतर तरीका यह होगा कि जैसे ही आप max_length से अधिक हो जाते हैं, लूप से बाहर निकल जाते हैं, इस तरह आप बिना किसी कारण के बाकी सूची पर लूप नहीं कर रहे हैं:

for s in s_tuples:
    if l > max_length:
        break
    output.append(s[0])
    l += len(get_words_from(s[0]))
return ''.join(output)
1
Dima Tisnek 8 पद 2014, 12:17

सबसे पहले, यदि अधिकतम लंबाई अगले पुनरावृत्ति तक पहुंच जाती है, तो मुझे लूप से बाहर निकलने को स्थगित करने का कोई कारण नहीं दिखता है।

तो, अपना कोड बदलते हुए, मैं निम्नलिखित कोड के साथ आया हूं:

s_tuples = [('Where are you',1),('What about the next day',2),('When is the next event',3)]


def get_words_number(s):
    return len(s.split())


def truncate(s_tuples, max_length):
    tot_len = 0
    output = []
    for s in s_tuples:
        output.append(s[0])
        tot_len += get_words_number(s[0])
        if tot_len >= max_length:
            break
    return ' '.join(output)


print truncate(s_tuples,3)

दूसरा, मुझे वास्तव में यह पसंद नहीं है कि एक अस्थायी वस्तु output बनाई जाए। हम join मेथड को इटरेटर के साथ फीड कर सकते हैं जो जानकारी को डुप्लिकेट किए बिना प्रारंभिक सूची में पुनरावृति करता है।

def truncate(s_tuples, max_length):

    def stop_iterator(s_tuples):
        tot_len = 0
        for s,num in s_tuples:
            yield s
            tot_len += get_words_number(s)
            if tot_len >= max_length:
                break

    return ' '.join(stop_iterator(s_tuples))


print truncate(s_tuples,3)

साथ ही, आपके उदाहरणों में, आउटपुट अधिकतम शब्दों के सेट से थोड़ा बड़ा है। यदि आप चाहते हैं कि शब्दों की संख्या हमेशा सीमा से कम हो (लेकिन फिर भी अधिकतम संभव हो), तो सीमा के विरुद्ध जाँच करने के बाद केवल yield डालें:

def truncate(s_tuples, max_length):

    def stop_iterator(s_tuples):
        tot_len = 0
        for s,num in s_tuples:
            tot_len += get_words_number(s)
            if tot_len >= max_length:
                if tot_len == max_length:
                    yield s
                break
            yield s

    return ' '.join(stop_iterator(s_tuples))


print truncate(s_tuples,5)
2
ovgolovin 9 नवम्बर 2011, 04:45

आपका कोड सीमा समाप्त होने पर नहीं रुकता है। "max_length" एक बुरा नाम है ... यह "अधिकतम लंबाई" नहीं है, आपका कोड इसे पार करने की अनुमति देता है (जैसा कि आपके पहले उदाहरण में है) - क्या यह जानबूझकर है? "एल" एक बुरा नाम है; चलो इसे tot_len कहते हैं। आप तब भी चलते रहते हैं जब tot_len == max_length। आपका उदाहरण स्पेस के साथ जुड़ना दिखाता है लेकिन आपका कोड ऐसा नहीं करता है।

आपको शायद कुछ चाहिए:

tot_len = 0
output = []
for s in s_tuples:
    if tot_len >= max_length:
        break
    output.append(s[0])
    tot_len += len(get_words_from(s[0]))
return ' '.join(output)
1
John Machin 9 नवम्बर 2011, 00:41

max_length को क्या नियंत्रित करना चाहिए? लौटाई गई सूची में शब्दों की कुल संख्या? मुझे उम्मीद है कि पांच में से एक max_length केवल 5 शब्द देगा, 8 नहीं।

संपादित करें: मैं दो सूचियों को चारों ओर रखूंगा क्योंकि मुझे लगता है कि इसे पढ़ना आसान है, लेकिन कुछ अतिरिक्त ओवरहेड पसंद नहीं कर सकते हैं:

def restrictWords(givenList, whenToStop):
    outputList = []
    wordList = []
    for pair in givenList:
        stringToCheck = pair[0]
        listOfWords = stringToCheck.split()
        for word in listOfWords:
            wordList.append(word)
        outputList.append( stringToCheck )
        if len( wordList ) >= whenToStop:
            break
    return outputList

अभीतक के लिए तो

testList = [ ('one two three',1),
             ('four five',2),
             ('six seven eight nine',3) ]

2 आपको ['one two three'] देना चाहिए 3 आपको ['one two three'] देना चाहिए 4 आपको ['one two three', 'four five'] देना चाहिए

1
aeroNotAuto 9 नवम्बर 2011, 00:59

यदि NumPy सूची समझ कार्यों का उपयोग करके निम्नलिखित समाधान उपलब्ध है।

import numpy as np

# Get the index of the last clause to append.
s_cumlen = np.cumsum([len(s[0].split()) for s in s_tuples])
append_until = np.sum(s_cumlen < max_length)

return ' '.join([s[0] for s in s_tuples[:append_until+1]])

स्पष्टता के लिए: s_cumlen में आपके स्ट्रिंग्स की शब्द गणना का संचयी योग होता है।

>>> s_cumlen
array([ 3,  8, 13])
0
David Alber 9 नवम्बर 2011, 01:42