int

2013-02-26 126 views
9

की सूची में tuples की पायथन सूची तो, मेरे पास x=[(12,), (1,), (3,)] (टुपल्स की सूची) है और मुझे x=[12, 1, 3] (पूर्णांक की सूची) संभवतः सर्वोत्तम तरीके से चाहिए? क्या आप कृपया मदद कर सकते हैं?int

+3

समाधान पर अपना प्रयास शामिल करने के लिए कृपया अपना प्रश्न संपादित करें। धन्यवाद। – bernie

+0

आपके टुपल्स हमेशा एक ही रूप में हैं? '(एन,)'? –

+1

एक वैकल्पिक 'ज़िप (* x) [0] 'या' अगला (ज़िप (* x))' Py3k – JBernardo

उत्तर

5
y = [i[0] for i in x] 

यह केवल एक तत्व प्रति ट्यूपल के लिए काम करता है, हालांकि।

हालांकि, अगर आप टपल प्रति एक से अधिक तत्वों है, तो आप एक से थोड़ा अधिक जटिल सूची समझ का उपयोग कर सकते हैं:

y = [i[j] for i in x for j in range(len(i))] 

संदर्भ:

x = [i[0] for i in x] 

स्पष्टीकरण: List Comprehensions

+1

@pedro - हां, इसमें हमेशा एक तत्व होगा। – NullException

+0

दूसरे के लिए: यदि आपको अनुक्रमों के किसी अनुक्रम को फ़्लैट करने की आवश्यकता है, तो ['itertools'] (http://docs.python.org/2/library/itertools.html#recipes) दस्तावेज़ों में एक नुस्खा है जिसे ' flatten'। शायद यह और सूची समझ दोनों को समझने लायक है। – abarnert

+1

क्या आप 'के लिए' के ​​क्रम को उलटा नहीं करना चाहिए? – phant0m

2

बस ऐसा करने :

>>> x=[(12,), (1,), (3,)] 

>>> x 
[(12,), (1,), (3,)] 

>>> [i for i in x] 
[(12,), (1,), (3,)] 

>>> [i[0] for i in x] 
[12, 1, 3] 
1

यह सबसे कारगर तरीका है:

x = [i for i, in x] 

या, समतुल्य रूप

x = [i for (i,) in x] 

यह थोड़ा धीमा है:

x = [i[0] for i in x] 
+0

क्या आप दक्षता अंतर के बारे में निश्चित हैं? 3.3.0 में 1 एम-एलिमेंट 'लिस्ट' के साथ त्वरित परीक्षण में, उन्होंने क्रमशः 4.15 एमएमएस और 4.14 एमएमएस लिया- और ऐसा लगता है कि उसमें से 4ms से अधिक समय सूची को फिर से चलाने और एक नई सूची बनाने में बिताया गया था, इसलिए कुछ भी नहीं किसी भी तेजी से होने की संभावना है। यदि आप x को genexp में बदलते हैं और दो listcomps को एक डेनेक्सप के साथ 'डेक (genexp, maxlen = 0)' में खिलाया जाता है, तो मुझे 1.36us बनाम 1.32us मिलता है। – abarnert

+0

अधिक महत्वपूर्ण बात यह है कि आप किस परिदृश्य को कल्पना कर रहे हैं कि कोई भी किस पर ध्यान रखेगा कि इनमें से कौन सा अधिक कुशल है? – abarnert

+1

किसी भी तरह से एसओ पर पाइथन के लिए यह दक्षता प्रवृत्ति कहां से आ रही है? मेरे लिए, यह अधिक अंक प्राप्त करने के लिए एक चाल की तरह लगता है। – phant0m

0

आप नक्शे फ़ंक्शन का उपयोग कर सकते हैं ....

map(lambda y: y[0], x) 
+2

यदि आप 'मानचित्र' का उपयोग करने जा रहे हैं, तो आप 'lambda' के बजाय' itemgetter' का भी उपयोग कर सकते हैं। – abarnert

11

आपने यह नहीं कहा कि "सर्वश्रेष्ठ" से आपका क्या मतलब है, लेकिन संभवतः आपका मतलब है "सबसे पायथनिक" या "सबसे अधिक पढ़ने योग्य" या ऐसा कुछ।

F3AR3DLEGEND द्वारा दी गई सूची समझ शायद सबसे सरल है। कोई भी जो सूची समझ को पढ़ना जानता है उसे तुरंत पता चलेगा कि इसका क्या अर्थ है।

y = [i[0] for i in x] 

हालांकि, अक्सर आपको एक सूची की आवश्यकता नहीं होती है, केवल कुछ ऐसा जो कि एक बार फिर से किया जा सकता है। यदि आपके पास x में अरबों तत्व हैं, तो एक अरब-तत्व y का निर्माण करने के लिए बस एक बार में एक तत्व एक बुरा विचार हो सकता है। तो, आप एक जनरेटर अभिव्यक्ति का उपयोग कर सकते हैं: आप कार्यात्मक प्रोग्रामिंग पसंद करते हैं

y = (i[0] for i in x) 

, आप map उपयोग करने के लिए पसंद कर सकते हैं। map का नकारात्मक पहलू आप इसे एक समारोह, न सिर्फ एक अभिव्यक्ति है, तो आप या तो एक lambda समारोह, या itemgetter उपयोग करने की आवश्यकता है जिसका अर्थ है पारित करने के लिए है कि है:

y = map(operator.itemgetter(0), x) 

अजगर 3 में, इस जनरेटर के बराबर है अभिव्यक्ति; यदि आप list चाहते हैं, तो इसे list पर पास करें। पायथन 2 में, यह list लौटाता है; यदि आप एक इटरेटर चाहते हैं, तो map के बजाय itertools.imap का उपयोग करें।

आप एक अधिक सामान्य सपाट समाधान चाहते हैं, तो आप एक अपने आप को लिख सकते हैं, लेकिन यह हमेशा इस तरह के सामान्य समाधान के लिए itertools को देख के लायक है, और वहाँ वास्तव में एक नुस्खा flatten है कि इस्तेमाल किया बुलाया "में से एक स्तर समतल है नेस्टिंग "।तो, कॉपी और पेस्ट अपने कोड (या pip install more-itertools) में है कि और तुम सिर्फ कर सकते हैं इस:

y = flatten(x) 

आप तो कैसे chain है पर, और उसके बाद में कैसे chain.from_iterable कार्यान्वित किया जाता है, और flatten कैसे कार्यान्वित किया जाता है पर नज़र डालें तो लागू किया गया, आप देखेंगे कि आप बिल्टिन के मामले में एक ही चीज़ लिख सकते हैं। लेकिन परेशान क्यों, flatten अधिक पठनीय और स्पष्ट होने जा रहा है?

अंत में, यदि आप (बेशक या जनरेटर अभिव्यक्ति,) एक नेस्टेड सूची समझ के जेनेरिक वर्जन को कम करना चाहते:

y = [j for i in x for j in i] 

हालांकि, नेस्टेड सूची comprehensions गलत पाने के लिए बहुत आसान है, दोनों को लिखित रूप में कर रहे हैं और पढ़ना। (ध्यान दें कि F3AR3DLEGEND, वही व्यक्ति जिसने सबसे सरल उत्तर दिया, ने भी घोंसला की समझ दी और उसे गलत पाया। अगर वह इसे खींच नहीं सकता है, तो क्या आप वाकई कोशिश करना चाहते हैं?) वास्तव में सरल मामलों के लिए, वे ' बहुत बुरा नहीं है, लेकिन फिर भी, मुझे लगता है कि flatten पढ़ने के लिए बहुत आसान है।

+0

तो tuple unpacking à la पैटर्न मिलान पर आपकी राय क्या है? –

+0

@PavelAnossov: इसके बारे में क्या? जब आप अलग-अलग नामों में एक टुपल को अनपैक करना चाहते हैं, तो यह स्पष्ट रूप से सही चीज़ है। जब आपके पास एक का टुपल होता है जिसे आप केवल एक ही मान में बदलना चाहते हैं, तो यह बिल्कुल स्पष्ट नहीं लगता है, लेकिन यह वास्तव में आपत्तिजनक नहीं है। – abarnert