2010-01-25 12 views
28
श्रेणीबद्ध करने के लिए

इस हानिरहित थोड़ा सूची को देखते हुए:अधिकांश pythonic तरीका तार

>>> lst = ['o','s','s','a','m','a'] 

मेरा लक्ष्य pythonically निम्नलिखित तरीके का प्रयोग करके थोड़ा शैतानों को श्रेणीबद्ध करने के लिए है:

ए सादा ol 'स्ट्रिंग कार्य करने के लिए काम किया हो, कम, कोई आयात

>>> ''.join(lst) 
'ossama' 

बी लैम्ब्डा, लंबाडा, लैम्ब्डा

>>> reduce(lambda x, y: x + y, lst) 
'ossama' 

सी वैश्वीकरण (, कुछ नहीं कर आयात सब कुछ)

>>> import functools, operator 
>>> functools.reduce(operator.add, lst) 
'ossama' 

कृपया इस उदार कार्य को प्राप्त करने के अन्य तरीकों का सुझाव pythonic।

कृपया रैंक (पायथनिक स्तर) और संक्षिप्त स्पष्टीकरण देने वाले समाधानों को रेट करें।

इस मामले में, सबसे अच्छा कोडिंग समाधान सबसे पाइथनिक समाधान है?

उत्तर

29

पाइथन ऑप्टिमाइज़ेशन पर गिडो के essay पर एक नज़र डालें, इसमें संख्याओं को स्ट्रिंग्स में कनवर्ट करना शामिल है। जब तक आपके पास अच्छा अन्यथा करने का कारण नहीं है, तो join उदाहरण का उपयोग करें।

55
''.join(lst) 

केवल pythonic तरीका:

  • स्पष्ट (है कि क्या सभी बड़े लड़कों करते हैं और वे क्या देखने की उम्मीद) (सभी संस्करणों में कोई अतिरिक्त आयात की जरूरत है, स्थिर),
  • सरल ,
  • तेज़ (सी में लिखा गया) और
  • संक्षिप्त (रिक्त स्ट्रिंग पर पुनरावृत्त तत्वों में शामिल हों!)।
+2

जबकि कम आधारित समाधान सुरुचिपूर्ण हैं और मेरे में कार्यात्मक प्रोग्रामर उनकी सराहना करता है, मुझे सहमत होना चाहिए कि() वास्तव में एकमात्र पायथनिक समाधान है। – liwp

+1

मूक गॉस्ट सही है। स्ट्रिंग्स में एक जॉइन विधि होती है जो पुनरावृत्तियों को स्वीकार करती है, इसलिए किसी और चीज का उपयोग करना पाइथोनिक नहीं है। – stefanw

+0

तो - लोग, कृपया, "bytearray" मूल प्रकार मेरे उत्तर को देखें)। हालांकि, पाइथन 2.5 तक जुड़ा हुआ है। – jsbueno

5

यहाँ कम से कम pythonic तरीका है:

out = "" 
for x in range(len(lst)): 
    for y in range(len(lst)): 
    if x + y == len(lst)-1: 
     out = lst[y] + out 
+3

मैं शर्त लगाता हूं कि उसमें पाइथोनिसिटी को कम करने के तरीके हैं। ;) –

+0

वास्तव में उसने जो पूछा वह नहीं है लेकिन मैं आपका बिंदु देखता हूं ..... :-) –

5

मैं अपने आप को "में शामिल होने" जिस तरह से उपयोग करें, लेकिन अजगर 2.6 से एक आधार प्रकार है कि छोटे से प्रयोग किया जाता है है: bytearray।

बाइटरेरेज़ ग्रंथ युक्त स्ट्रिंग के लिए अविश्वसनीय रूप से उपयोगी हो सकते हैं, क्योंकि सबसे अच्छी बात यह है कि यूनिकोड में, "जुड़ने" का तरीका है - लेकिन यदि आप इसके बजाय बाइनरी डेटा से निपट रहे हैं, तो बाइटरेरे हो सकता है दोनों अधिक pythonic और अधिक कुशल:

>>> lst = ['o','s','s','a','m','a'] 
>>> a = bytearray(lst) 
>>> a 
bytearray(b'ossama') 
>>> print a 
ossama 

यह एक डेटा प्रकार में बनाया गया है: कोई आयात की जरूरत - बस उसके बाद का उपयोग करें - और आप एक सूची की एक bytearray isntead का उपयोग के साथ शुरू करने के लिए कर सकते हैं - तो उन्हें करना चाहिए "जुड़ें" की तुलना में अधिक प्रभावशाली बनें, क्योंकि बायटियर के लिए स्ट्रिंग प्रस्तुति प्राप्त करने के लिए कोई डेटा कॉपी नहीं है।

SilenGhost से
+0

hmm..just चेक किया गया: "बाइटियर" कन्स्ट्रक्टर भी एक यूनिकोड स्ट्रिंग और "एन्कोडिंग" तर्क प्राप्त कर सकता है ताकि यह सौदा कर सके यूनिकोड के साथ भी। जैसे। : a = bytearray (u "déja-vu", एन्कोडिंग = "utf8") – jsbueno

+1

सिवाय इसके कि उपनिवेश न तो पाइथोनिक और न ही कुशल हैं। वे पूरी तरह से अलग उद्देश्य के लिए हैं, और py2.6 में उनका व्यवहार py3k जैसा नहीं है। – SilentGhost

+0

@SilentGost: आपकी प्रतिक्रिया के लिए धन्यवाद - मैं इसके बारे में और कहां पढ़ सकता हूं? और यहां तक ​​कि यदि वे पहले के रूप में प्रकट नहीं होते हैं, तो मुझे संदेह है कि प्रतिभागिता के लिए प्रति भाग एक नई स्ट्रिंग ऑब्जेक्ट के निर्माण के कारण "जुड़ें" तेजी से हो सकता है। (मैं आज बाद में कुछ बेंचमार्किंग करना चाहता हूं) – jsbueno

3

महान जवाब लेकिन, सिर्फ प्रस्तुत reduce "वैकल्पिक"

जब तक आप एक बहुत बहुत बहुत अच्छा + या operator.add का उपयोग कर तार जोड़ करने का कारण मिल गया है (सबसे अक्सर एक बारे में कुछ शब्द , कि आपके पास कुछ निश्चित, स्ट्रिंग्स की निश्चित संख्या है), आपको हमेशा join का उपयोग करना चाहिए।

सिर्फ इसलिए कि प्रत्येक + एक नई स्ट्रिंग उत्पन्न करता है जो दो स्ट्रिंग्स का संगतता है, जब तक कि इसमें शामिल न हों केवल एक अंतिम स्ट्रिंग उत्पन्न करता है। तो, कल्पना करें कि आप 3 तार मिल गया है:

A + B + C 
--> 
D = A + B 
final = D + C 

ठीक है, बहुत ज्यादा नहीं लगता नहीं है, लेकिन आप इसके अलावा डी के लिए स्मृति आरक्षण स्ट्रिंग की वजह से अजगर उपयोग मिल गया है, एक नया, मध्यवर्ती पैदा , स्ट्रिंग, यह किसी भी तरह महंगा है ...

अब, 5 तार

A + B + C + D + E 
--> 
F = A + B 
G = F + C 
H = G + D 
final = H + E 

सबसे अच्छा परिदृश्य अगर हम (ए + बी) + (सी + डी) + ई करते हैं, हम करेंगे मान लिया जाये कि (के साथ अंत में स्मृति पर एक ही समय में तीन इंटरमीडिएट तार होते हैं), जो 3 इंटरमीडिएट स्ट्रिंग उत्पन्न कर रहा है ... आपको एक नया पायथन ऑब्जेक्ट उत्पन्न करना होगा, पुनर्विक्रेता मेमोरी स्पेस, मेमोरी को कुछ बार रिलीज़ करें ... इसके अलावा एक पायथन फ़ंक्शन (जो छोटा नहीं है) को कॉल करने का ओवरहेड

अब 200 स्ट्रिंग्स के बारे में सोचें। हम एक हास्यास्पद बड़ी संख्या में इंटरमीडिएट स्ट्रिंग्स के साथ समाप्त हो जाएंगे, जिनमें से प्रत्येक एक पाइथन पर पूरी सूची होने पर काफी समय ले रहा है, और operator.add फ़ंक्शंस को कॉल कर रहा है, प्रत्येक इसके ओवरहेड के साथ ... यदि आप इसका उपयोग करते हैं reduce फ़ंक्शंस, इससे मदद नहीं मिलेगी। यह एक समस्या है जिसे एक अलग दृष्टिकोण के साथ प्रबंधित किया जाना चाहिए: join, जो केवल एक पूर्ण पायथन स्ट्रिंग, अंतिम एक उत्पन्न करता है और एक पायथन फ़ंक्शन को कॉल करता है।

(बेशक, join, या अन्य इसी तरह, विशेष सरणियों के लिए समारोह)

16
बेशक

यह join है। मुझे कैसे पता चलेगा? आइए इसे वास्तव में बेवकूफ तरीके से करें:
यदि समस्या केवल 2 स्ट्रिंग जोड़ रही थी, तो आप अधिकतर str1 + str2 का उपयोग करेंगे। अगले स्तर तक पहुंचने में क्या लगता है? सहज रूप से, अधिकांश (मुझे लगता है) के लिए, sum का उपयोग करना होगा। चलो देखते हैं कि यह कैसे जाता है:

In [1]: example = ['a', 'b', 'c'] 
In [2]: sum(example, '') 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython console> in <module>() 
TypeError: sum() can't sum strings [use ''.join(seq) instead] 

वाह! पायथन ने मुझे बताया कि क्या उपयोग करना है! :)

संबंधित मुद्दे