python - पायथन शामिल हों: list.join(स्ट्रिंग) की बजाय string.join(list) क्यों है?




(6)

list.join(string) बजाय string.join(list) क्यों है?

ऐसा इसलिए है क्योंकि join एक "स्ट्रिंग" विधि है! यह किसी भी तार से एक स्ट्रिंग बनाता है। अगर हम सूचियों पर विधि को फंसते हैं, तो हमारे पास इयरिएबल्स के बारे में क्या है जो सूचियां नहीं हैं?

क्या होगा यदि आपके पास स्ट्रिंग्स का टुपल है? यदि यह एक list विधि थी, तो तत्वों को एक स्ट्रिंग में शामिल करने से पहले आपको स्ट्रिंग्स के इस तरह के प्रत्येक इवेंटेटर को एक list रूप में डालना होगा! उदाहरण के लिए:

some_strings = ('foo', 'bar', 'baz')

आइए अपनी खुद की सूची में शामिल हों विधि:

class OurList(list): 
    def join(self, s):
        return s.join(self)

और इसका उपयोग करने के लिए, ध्यान दें कि हमें पहले दोहराए जाने वाले तारों में शामिल होने के लिए प्रत्येक पुनरावृत्ति से एक सूची बनाना होगा, स्मृति और प्रसंस्करण शक्ति दोनों को बर्बाद कर देना होगा:

>>> l = OurList(some_strings) # step 1, create our list
>>> l.join(', ') # step 2, use our list join method!
'foo, bar, baz'

तो हम देखते हैं कि हमें बिल्टिन स्ट्रिंग विधि का उपयोग करने के बजाय, हमारी सूची विधि का उपयोग करने के लिए एक अतिरिक्त चरण जोड़ना होगा:

>>> ' | '.join(some_strings) # a single step!
'foo | bar | baz'

जेनरेटर के लिए प्रदर्शन चेतावनी

एल्गोरिदम पाइथन str.join साथ अंतिम स्ट्रिंग बनाने के लिए उपयोग करता है, वास्तव में दो बार str.join को पार करना होता है, इसलिए यदि आप इसे जनरेटर अभिव्यक्ति प्रदान करते हैं, तो इसे अंतिम स्ट्रिंग बनाने से पहले इसे पहले सूची में पूरा करना होगा।

इस प्रकार, जेनरेटर के आसपास गुजरते समय आमतौर पर सूची समझ से बेहतर होता है, str.join एक अपवाद है:

>>> import timeit
>>> min(timeit.repeat(lambda: ''.join(str(i) for i in range(10) if i)))
3.839168446022086
>>> min(timeit.repeat(lambda: ''.join([str(i) for i in range(10) if i])))
3.339879313018173

फिर भी, str.join ऑपरेशन अभी भी एक "स्ट्रिंग" ऑपरेशन है, इसलिए यह अभी भी विविध पुनरावृत्तियों की तुलना में str ऑब्जेक्ट पर रखने के लिए समझ में आता है।

यह हमेशा मुझे भ्रमित कर दिया है। ऐसा लगता है कि यह अच्छा होगा:

my_list = ["Hello", "world"]
print my_list.join("-")
# Produce: "Hello-world"

उसके बाद यह:

my_list = ["Hello", "world"]
print "-".join(my_list)
# Produce: "Hello-world"

क्या ऐसा कोई विशिष्ट कारण है?


इसे विभाजित करने के लिए प्राकृतिक ऑर्थोगोनल ऑपरेशन के रूप में सोचें।

मैं समझता हूं कि यह किसी भी चीज़ पर लागू क्यों है और इसलिए आसानी से सूची में लागू नहीं किया जा सकता है।

पठनीयता के लिए, मैं इसे भाषा में देखना चाहता हूं लेकिन मुझे नहीं लगता कि यह वास्तव में व्यवहार्य है - अगर अस्थिरता एक इंटरफ़ेस थी तो इसे इंटरफ़ेस में जोड़ा जा सकता है लेकिन यह केवल एक सम्मेलन है और इसलिए कोई केंद्रीय तरीका नहीं है इसे चीजों के सेट में जोड़ें जो पुनरावृत्त हैं।


क्योंकि सूची वर्ग के बजाय, join() विधि स्ट्रिंग क्लास में है?

मैं मानता हूं कि यह मजाकिया लग रहा है।

देखें http://www.faqs.org/docs/diveintopython/odbchelper_join.html :

ऐतिहासिक नोट जब मैंने पहली बार पाइथन सीखा, तो मुझे उम्मीद थी कि एक सूची की विधि बनें, जो डेलीमीटर को तर्क के रूप में ले जाएगा। बहुत से लोग एक ही तरह से महसूस करते हैं, और शामिल विधि के पीछे एक कहानी है। पायथन 1.6 से पहले, स्ट्रिंग्स में ये सभी उपयोगी विधियां नहीं थीं। एक अलग स्ट्रिंग मॉड्यूल था जिसमें सभी स्ट्रिंग फ़ंक्शन शामिल थे; प्रत्येक समारोह ने अपनी पहली तर्क के रूप में एक स्ट्रिंग ली। कार्यों को तारों पर खुद को रखने के लिए काफी महत्वपूर्ण समझा जाता था, जो कम, ऊपरी और विभाजित जैसे कार्यों के लिए समझ में आया था। लेकिन कई हार्ड-कोर पायथन प्रोग्रामर ने नए जुड़ने के तरीके पर आक्षेप किया, बहस करते हुए कि यह सूची की एक विधि होनी चाहिए, या यह बिल्कुल नहीं बढ़ना चाहिए बल्कि पुराने स्ट्रिंग मॉड्यूल का हिस्सा रहना चाहिए (जो अभी भी बहुत सारे हैं इसमें उपयोगी सामान का)। मैं विशेष रूप से नई जॉइन विधि का उपयोग करता हूं, लेकिन आपको कोड को किसी भी तरह से लिखा जाएगा, और यदि यह वास्तव में आपको परेशान करता है, तो आप पुराने स्ट्रिंग.जॉइन फ़ंक्शन का उपयोग कर सकते हैं।

--- मार्क पिलग्रीम, पाइथन में गोता लगाएँ


मुख्य रूप से क्योंकि someString.join() का परिणाम एक स्ट्रिंग है।

अनुक्रम (सूची या टुपल या जो कुछ भी) परिणाम में प्रकट नहीं होता है, केवल एक स्ट्रिंग। क्योंकि परिणाम एक स्ट्रिंग है, यह एक स्ट्रिंग की विधि के रूप में समझ में आता है।


स्ट्रिंग विधियों में इस पर चर्चा की गई ... आखिर में पाइथन-देव आचिव में धागा, और Guido द्वारा स्वीकार किया गया था। यह धागा जून 1 999 में शुरू हुआ, और str.join को पायथन 1.6 में शामिल किया गया था जिसे सितंबर 2000 में जारी किया गया था (और यूनिकोड समर्थित)। पाइथन 2.0 ( join str विधियों सहित) अक्टूबर 2000 में जारी किया गया था।

  • इस धागे में चार विकल्प प्रस्तावित किए गए थे:
    • str.join(seq)
    • seq.join(str)
    • seq.reduce(str)
    • अंतर्निहित फ़ंक्शन के रूप में join
  • Guido न केवल list , tuple एस, लेकिन सभी अनुक्रम / iterables का समर्थन करना चाहता था।
  • seq.reduce(str) नए comers के लिए मुश्किल है।
  • seq.join(str) अनुक्रमों से str / unicode तक अप्रत्याशित निर्भरता प्रस्तुत करता है।
  • अंतर्निर्मित फ़ंक्शन के रूप में join() केवल विशिष्ट डेटा प्रकारों का समर्थन करेगा। इसलिए नामस्थान में निर्मित का उपयोग करना अच्छा नहीं है। यदि join() कई डेटाटाइप का समर्थन करता है, तो अनुकूलित कार्यान्वयन करना कठिन होगा, यदि __add__ विधि का उपयोग करके लागू किया गया है तो यह ओ (एन²) है।
  • sep स्ट्रिंग ( sep ) को छोड़ा नहीं जाना चाहिए। स्पष्ट से स्पष्ट स्पष्ट है।

इस धागे में कोई अन्य कारण नहीं है।

यहां कुछ अतिरिक्त विचार हैं (मेरा अपना, और मेरे दोस्त):

  • यूनिकोड समर्थन आ रहा था, लेकिन यह अंतिम नहीं था। उस समय यूटीएफ -8 यूसीएस 2/4 को बदलने की सबसे अधिक संभावना थी। यूटीएफ -8 तारों की कुल बफर लंबाई की गणना करने के लिए इसे वर्ण कोडिंग नियम जानने की आवश्यकता है।
  • उस समय, पायथन ने पहले से ही एक सामान्य अनुक्रम इंटरफ़ेस नियम पर निर्णय लिया था जहां कोई उपयोगकर्ता अनुक्रम-जैसी (पुनरावर्तनीय) कक्षा बना सकता था। लेकिन पायथन 2.2 तक निर्मित अंतर्निहित प्रकारों का समर्थन नहीं करता था। उस समय बुनियादी पुनरावर्तनीय वर्ग प्रदान करना मुश्किल था (जिसे किसी अन्य टिप्पणी में उल्लिखित किया गया है)।

Guido का निर्णय एक ऐतिहासिक मेल में दर्ज किया गया है, str.join(seq) पर निर्णय str.join(seq) :

मजेदार, लेकिन यह सही प्रतीत होता है! बैरी, इसके लिए जाओ ...
- गुइडो वैन रॉसम


- घोषणा करें कि आप एक सूची में शामिल हो रहे हैं और एक स्ट्रिंग में परिवर्तित हो रहे हैं। यह परिणाम उन्मुख है। (केवल आसान स्मृति और समझ के लिए)

मैं आपके संदर्भ के लिए विधियों_of_string का एक विस्तृत cheatsheet बनाते हैं।

string_methonds_44 = {
    'convert': ['join','split', 'rsplit','splitlines', 'partition', 'rpartition'],
    'edit': ['replace', 'lstrip', 'rstrip', 'strip'],
    'search': ['endswith', 'startswith', 'count', 'index', 'find','rindex', 'rfind',],
    'condition': ['isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isnumeric','isidentifier',
                  'islower','istitle', 'isupper','isprintable', 'isspace', ],
    'text': ['lower', 'upper', 'capitalize', 'title', 'swapcase',
             'center', 'ljust', 'rjust', 'zfill', 'expandtabs','casefold'],
    'encode': ['translate', 'maketrans', 'encode'],
    'format': ['format', 'format_map']}




join