2010-03-24 32 views
12

मैं एक सूची है के भीतर सूची में आइटम जोड़,, मान लें कि a = [[1,2],[3,4],[5,6]]एक सूची समझ

मैं सूची a में प्रत्येक आइटम के लिए स्ट्रिंग 'a' जोड़ना चाहते हैं।

जब मैं का उपयोग करें:

a = [x.append('a') for x in a] 

यह रिटर्न [None,None,None]

लेकिन अगर मैं का उपयोग करें:

a1 = [x.append('a') for x in a] 

तो यह कुछ अजीब है।

a, लेकिन a1[[1,2,'a'],[3,4,'a'],[5,6,'a']] नहीं है।

मुझे समझ में नहीं आता कि पहला कॉल [None, None, None] क्यों देता है और न ही के बजाय a पर दूसरा परिवर्तन क्यों करता है।

उत्तर

7

पहले मामले के लिए, [None, None, None] लौटने का कारण यह है कि list.append फ़ंक्शन None लौटाता है, और यही वह सूची में संग्रहीत करता है।

दूसरे मामले में, ऐसा इसलिए है क्योंकि सूची उत्परिवर्तनीय है, और प्रत्येक बार जब आप मान जोड़ते हैं, तो मूल सूची संशोधित होती है।

आपको जो चाहिए वह एक गैर-जगह जगह एपेंड ऑपरेटर है, जैसे +। यानी [x + ['a'] for x in a]

23

list.append सूची को स्वयं ही बदलता है और None देता है। सूची की समझ परिणाम को संग्रहीत करने के लिए होती है, जो आप इस मामले में नहीं चाहते हैं यदि आप मूल सूचियों को बदलना चाहते हैं।

>>> x = [[1, 2], [3, 4], [5, 6]] 
>>> for sublist in x: 
...  sublist.append('a') 
... 
>>> x 
[[1, 2, 'a'], [3, 4, 'a'], [5, 6, 'a']] 
3

(यह माइक ग्राहम और Sykora से जवाब का एक संयोजन है):

आप केवल यथा-स्थान मान बदलना चाहते हैं, के लिए लूप एक नियमित रूप से, और नहीं एक सूची समझ की कोशिश :

for sublist in a: 
    sublist.append('a') 

आप एक अकेला छोड़ दो, और a1 में परिणाम डाल करना चाहते हैं:

a1 = [sublist + ['a'] for sublist in a] 

वे के रूप में समझाया गया, append सूची को संशोधित करता है, लेकिन कोई नहीं देता है, जबकि + अकेले सूची छोड़ देता है, लेकिन एक नई, संलग्न सूची देता है।

+3

यह ए 1 = [सब्लिस्ट + ['ए'] होना चाहिए जिसमें उपन्यास के लिए एक होना चाहिए]। 'ए' के ​​चारों ओर ब्रैकेट नोट करें। –

+0

हूप्स। फिक्स्ड। धन्यवाद। – Oddthinking

0

a = छोड़ दो और a पर पक्ष प्रभाव का उपयोग करें:

[x.append('a') for x in a] 
print a 
+2

कृपया, नहीं। अपने साइड इफेक्ट्स का उपयोग करने के लिए सिर्फ एक सूची समझ को फेंकना खराब रूप है; आपका सुझाव काम करता है, लेकिन यह समान 'मानचित्र' उपयोग की तरह ही डूब गया है। स्पष्ट से स्पष्ट स्पष्ट है; एक सूची समझ के बजाय एक लूप का उपयोग करें। – tzot

6

के रूप में अन्य लोगों ने कहा, append सूची ही mutates और आप एक चर के लिए असाइन करें नहीं करना चाहिए। इसे निष्पादित करने से इसका डेटा बदल जाता है, जो प्रभावी रूप से इसे इंगित करने वाले सभी को अद्यतन करता है।

लेकिन, वहाँ एक चाल का उपयोग मैं जब मैं जबकि मौजूदा वस्तुओं परिवर्तनशील (बजाय a=[x + ['a'] for x in a] का उपयोग कर नए लोगों को निर्माण, इस मामले में, या विशेष रूप से x + ['a']) एक कार्यात्मक * तरह से काम करना चाहते हैं।

इसलिए, यदि आप बहादुर हैं पर्याप्त आप भी ऐसा कर सकते हैं:

>>> a=[[1,2],[3,4],[5,6]] 
>>> a=[x.append('a') or x for x in a] 
>>> a 
[[1, 2, 'a'], [3, 4, 'a'], [5, 6, 'a']] 

यह काम करता है क्योंकि append रिटर्न None, और or पर जारी है एक सच-y मूल्य के लिए खोज करने के लिए है, जो xहै (यह list है जिसमें कम से कम इसमें शामिल किया गया था)।

मुझे इसकी आवश्यकता क्यों है?

आप एक सूची हैं और आप एक नई सूची के लिए इसे के सदस्यों में से कुछ डालें, और उसके अनुसार संदर्भ अद्यतन करना चाहते:

>>> all = [[], [], [], []] 

में से कुछ:

तो तुम सूची all है यह डाला जाता है और एक नई सूची x को अद्यतन किया जाता है:

>>> x = [i.append('x') or i for i in all[:2]] 
>>> x 
[['x'], ['x']] 

all से कुछ भी डाला जाता है और यू है एक सूची y को pdated:

>>> y = [i.append('y') or i for i in all[1:3]] 

all अद्यतन किया जाता है:

>>> all 
[['x'], ['x', 'y'], ['y'], []] 

लेकिन x भी अद्यतन किया जाता है:

>>> x 
[['x'], ['x', 'y']] 

और y अपेक्षा के अनुरूप उत्पन्न होता है:

>>> y 
[['x', 'y'], ['y']] 

कुल मिलाकर, सरल कार्यों के लिए, मैं for लूप को स्पष्ट रूप से अद्यतन करने का सुझाव देना चाहता हूं। यह पाइथोनिक माना जाता है।

def more_functional_append(self, x): 
    self.append(x) 
    return self 
  • functional programming, अनिवार्य रूप से एक ही बात कर रही है हर बयान पर और नहीं होने साइड इफेक्ट (ताकि आधारित है:

    तकनीकी तौर पर, बोल यदि आप सूची वर्ग के लिए जाने की अनुमति थी, तो आप इस एक समारोह कर सकता है , उत्परिवर्तन और वापसी नहीं)। append बहुत ही कार्यात्मक नहीं है क्योंकि यह एक सूची को बदलता है (शुद्ध कार्यात्मक प्रोग्रामिंग में केवल अपरिवर्तनीय वस्तुएं होती हैं) और अन्य क्रियाओं (कार्यों) को पास करने के लिए परिणाम नहीं लौटाती है। कार्यात्मक प्रोग्रामिंग अवधारणाओं का उपयोग करके आप महान बड़े एक-लाइनर बना सकते हैं, कोई भी पढ़ सकता है, जिसे "नौकरी सुरक्षा" या "खराब कोड" भी कहा जाता है।

+0

आज मेरे पास इस उत्तर पर एक अलग दृश्य है इसलिए यदि आप इसे पढ़ रहे हैं तो कृपया टिप्पणी करें ताकि मैं इसे अपडेट कर सकूं। यहां कार्यात्मक प्रोग्रामिंग के लिए एक गायब कोर फीचर है जो अपरिपक्वता है और मुझे उस पर विस्तार करना चाहिए। –

1

तुम इतनी तरह, एक सूची समझ के भीतर सूची अलावा उपयोग कर सकते हैं:

एक = [x + [ 'एक'] एक में एक्स के लिए]

यह वांछित देता है एक के लिए परिणाम। लूप से पहले एक चर नाम से ['ए'] असाइन करके इस मामले में इसे और अधिक कुशल बना सकता है, लेकिन यह निर्भर करता है कि आप क्या करना चाहते हैं।

0

आपकी सूची समझ के पहले मूल्य असाइनमेंट में एक विशेषता त्रुटि, 'noneType' ऑब्जेक्ट में कोई विशेषता नहीं है 'संलग्न करें', यह समझाने में सहायता करता है कि आपकी सूची, ए, किसी के साथ क्यों लोड नहीं की जाएगी। त्रुटि को फेंकने के लिए मेरा कंसोल प्राप्त करने के लिए, मैंने एक्स को सूची समझ के लिए एक चर के रूप में और इटरेटर के रूप में भी इस्तेमाल किया।

Traceback (most recent call last): 
x = [x.append('a') for x in a] 
AttributeError: 'NoneType' object has no attribute 'append' 

फिर, मैं वापस एक्स के लिए वापस लौट आया और यह वही त्रुटि फेंक दिया।

Traceback (most recent call last): 
a = [x.append('a') for x in a] 
AttributeError: 'NoneType' object has no attribute 'append' 
संबंधित मुद्दे