2012-04-24 15 views
36

अजगर 3 में मैं निम्नलिखित (विस्तारित Iterable Unpacking पर यह भी देखना PEP3132) कर सकते हैं:मीटर लंबाई n के टपल खोल कैसे <n चर

a, *b = (1, 2, 3) 
# a = 1; b = (2, 3) 

क्या मैं इसी तरह सुरुचिपूर्ण एक ही प्राप्त करने के लिए क्या कर सकते हैं पायथन 2.x में?


मुझे लगता है कि मैं एक तत्व का उपयोग और टुकड़ा करने की क्रिया आपरेशन इस्तेमाल कर सकते हैं पता है, लेकिन मुझे आश्चर्य है कि अगर वहाँ एक और अधिक pythonic रास्ता। मेरे कोड अब तक:

a, b = (1, 2, 3)[0], (1, 2, 3)[1:] 
# a = 1; b = (2, 3) 
+3

स्पष्ट स्लाइसिंग की तरह लगता है, या अवांछित मानों को कैप्चर करने के लिए एकाधिक अज्ञात _ अंडरस्कोर वर्र्स का उपयोग करना: x, _, _ = tup – jdi

+0

मुझे वास्तव में इस सुविधा के बारे में कोई प्रश्न है। क्या यह अजगर के ज़ेन का पालन करता है "स्पष्ट अंतर्निहित से बेहतर है।" – jdi

+1

@jdi यह स्पष्ट रूप से कहता है: मुझे 'ए' और अन्य सभी वस्तुओं को 'बी'' पर पहला आइटम प्राप्त करें। मुझे यह बहुत स्पष्ट लगता है ... – moooeeeep

उत्तर

27

मुझे पता चला है कि संबंधित PEP3132 रूप में अच्छी तरह पायथन 2.x के लिए कुछ उदाहरण देता है:

कई एल्गोरिदम एक "पहला, बाकी" में एक दृश्य बंटवारे की आवश्यकता होती है जोड़ी:

first, rest = seq[0], seq[1:] 

[...]

इसके अलावा, यदि दाएं हाथ का मूल्य एक सूची नहीं है, लेकिन एक पुनरावृत्त है, तो इसे स्लाइसिंग करने में सक्षम होने से पहले इसे एक सूची में परिवर्तित करना होगा;

समारोह तर्क सूची अनपैक दृष्टिकोण

की आवश्यकता है: यह अस्थायी सूची बनाने से बचने के लिए, एक

it = iter(seq) 
first = it.next() 
rest = list(it) 

अन्य इस सवाल का जवाब में दी गई दृष्टिकोण का सहारा लेना पड़ता है एक अतिरिक्त फ़ंक्शन परिभाषा/कॉल:

def unpack(first, *rest): 
    return first, rest 
first, rest = unpack(*seq) 

मुझे आश्चर्य है कि इसे फ़ंक्शन तर्क सूचियों को अनपॅक करने में क्यों लागू किया गया है लेकिन सामान्य टुपल अनपॅकिंग के लिए नहीं।

जेनरेटर दृष्टिकोण

Credits। एक कस्टम समारोह कार्यान्वयन की भी आवश्यकता है। पहले चर की संख्या से थोड़ा अधिक लचीला है।

def unpack_nfirst(seq, nfirst): 
    it = iter(seq) 
    for x in xrange(nfirst): 
    yield next(it, None) 
    yield tuple(it) 
first, rest = unpack_nfirst(seq, 1) 

सबसे pythonic शायद ऊपर पीईपी में उल्लेख किया है लोगों को हो सकता है, मुझे लगता है कि?

+1

मुझे एक ही बात आश्चर्य हुआ ... – jamylak

+3

आज के रूप में पीईपी 3132 केवल पायथन 3.x पर लागू होता प्रतीत होता है । मैं पुष्टि कर सकता हूं कि 'पहला, * आराम = seq' वाक्यविन्यास Python 2.7.5 में काम नहीं करता है (आप ऊपर 2.x का उल्लेख करते हैं)। –

+0

@ डेव इसे फिर से लाने के लिए धन्यवाद।मैंने उद्धृत भाग से अनुभाग को हटाने का फैसला किया, क्योंकि यह भ्रम का स्रोत था और उत्तर के लिए प्रासंगिक नहीं था। – moooeeeep

3

मैं गलत हो सकता है लेकिन जहां तक ​​मैं जानता हूँ कि

a, *b = (1, 2, 3) 

के रूप में टुकड़ा करने की क्रिया और अनुक्रमण tuples के लिए बस वाक्यात्मक चीनी है। मुझे यह उपयोगी लगता है लेकिन बहुत स्पष्ट नहीं है।

+1

पूरी तरह से ईमानदार होने के लिए, मैं अभी भी py2.7 पर हूं और यह 3.x नहीं देखा है अभी तक जोड़ा और यह एक टुकड़ा से भी ज्यादा उपयोगी नहीं दिखता है। आप स्पष्ट रूप से जानते हैं कि आप पहले तत्व चाहते हैं। चीनी को टुकड़ा करना पसंद करते हैं। – jdi

+0

जबकि यह केवल चीनी हो सकता है, यदि बायीं ओर आपकी सूची 2 से बड़ी है (ठीक है, शायद 6 या 7 से बड़ा हो) तो यह अधिक महत्वपूर्ण हो जाता है। स्लाइस के साथ समस्या यह है कि आपको '=' के दोनों किनारों पर कुछ मैन्युअल गिनती करना है जो संभावित रूप से कोड को बनाए रखने के लिए कठिन बनाता है। –

+0

मेरे पास सूचियों की एक सूची है, जिनमें से प्रत्येक लंबाई 4 या उससे अधिक है, और मेरी इच्छा है कि मैं इसे python2.7 में कर सकता हूं: 'a, b, c, d, * myList में उपयोग नहीं किया गया: <एक के साथ काम करें, बी, सी, डी> '। ए, बी, सी, डी के लिए उपयुक्त नामों के साथ, मुझे एक वैरिएबल को इंडेक्स करने से अधिक स्पष्ट लगता है। – mcmlxxxvi

4

मुझे नहीं लगता कि एक आप पोस्ट के अलावा कोई बेहतर तरीका है, लेकिन यहाँ एक वैकल्पिक iter

>>> x = (1,2,3) 
>>> i = iter(x) 
>>> a,b = next(i), tuple(i) 
>>> a 
1 
>>> b 
(2, 3) 
2

संदर्भ के बारे में सुनिश्चित नहीं हैं, लेकिन क्या .pop (0) के बारे में का उपयोग कर रहा है?

मुझे लगता है कि आपके उदाहरण में टुपल्स हैं, लेकिन यदि आप अपनी तरह की चीजें करना चाहते हैं, तो सूचियां अधिक उपयुक्त होंगी, मुझे लगता है?

b = [1,2,3] 
a = b.pop(0) 
8

मैं इस काम थोड़ा समारोह मिल गया है (जब तक कि वहाँ कुछ अच्छा कारण उन्हें अडिग होने के लिए प्रश्न में दिए गए नहीं है।):

def just(n, seq): 
    it = iter(seq) 
    for _ in range(n - 1): 
     yield next(it, None) 
    yield tuple(it) 

उदाहरण के लिए:

a, b, c = just(3, range(5)) 
print a, b, c 
## 0 1 (2, 3, 4) 

भी कम तर्क के साथ काम करता है:

a, b, c = just(3, ['X', 'Y']) 
print a, b, c 
## X Y() 

टिप्पणी के जवाब में, आप भी परिभाषित कर सकते हैं:

def take2(a, *rest): return a, rest 
def take3(a, b, *rest): return a, b, rest 
def take4(a, b, c, *rest): return a, b, rest 
... etc 

और इस तरह इसका इस्तेमाल:

p = (1,2,3) 
a, b = take2(*p) 
print a, b 
## 1 (2, 3) 
+1

जो मुझे इस विचार में लाता है: 'def foo (x, * y): x, y' लौटाएं और यह' ए, बी = foo (* (1,2,3)) होगा ... – moooeeeep

+1

@moooeeeep अच्छा विचार है, लेकिन आप 'ए, बी = foo (1,2,3) '', बी = foo (* (1,2,3)) के बजाय बस' ए, बी = foo (1,2,3) 'कर सकते हैं' – jamylak

+0

@moooeeeep: अद्यतन देखें)) – georg

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