2009-05-10 16 views
28

मैं अक्सर पाइथन सूचियों के वेक्टर जोड़ता हूं।पायथन में संक्षिप्त वेक्टर जोड़ना?

उदाहरण:

a = [0.0, 1.0, 2.0] 
b = [3.0, 4.0, 5.0] 

अब मैं एक करने के लिए ख जोड़ने के लिए परिणाम a = [3.0, 5.0, 7.0] प्राप्त करना चाहते हैं: मैं दो सूचियों इस तरह की है।

आमतौर पर मैं इस तरह कर रही अंत:

a[0] += b[0] 
a[1] += b[1] 
a[2] += b[2] 

वहाँ कुछ कुशल, मानक कम लिखकर यह करने के लिए रास्ता नहीं है?

अद्यतन: यह माना जा सकता है कि सूचियां लंबाई 3 की हैं और इसमें फ्लोट हैं।

उत्तर

27

मुझे नहीं लगता कि आप प्रश्न में प्रस्तावित 3 रकम की तुलना में एक तेजी से समाधान मिल जाएगा है। Numpy के फायदे बड़े वैक्टर के साथ दिखाई दे रहे हैं, और यदि आपको अन्य ऑपरेटरों की भी आवश्यकता है। numpy मैट्रिक्स के साथ विशेष रूप से उपयोगी है, चुड़ैल पायथन सूचियों के साथ करने के लिए चाल हैं।

फिर भी, अभी तक एक और तरीका यह करने के लिए: डी

In [1]: a = [1,2,3] 

In [2]: b = [2,3,4] 

In [3]: map(sum, zip(a,b)) 
Out[3]: [3, 5, 7] 

संपादित: आप भी itertools से izip, ज़िप

In [5]: from itertools import izip 

In [6]: map(sum, izip(a,b)) 
Out[6]: [3, 5, 7] 
+0

मजेदार तथ्य: 'मानचित्र' 'ज़िप 'कार्यक्षमता के साथ आता है। यह 'नक्शा (ऑपरेटर.एड, ए, बी) ' – Kos

0

आप एक ऐसा फ़ंक्शन बना सकते हैं जो सरणी का आकार प्राप्त कर लेता है, इसके माध्यम से लूप करता है और एक रिटर्न सरणी बनाता है जो इसे लौटाता है।

+0

धन्यवाद, लेकिन है कि बहुत ही कुशल प्रतीत नहीं होता। –

+0

@kotlinski। क्या? सरणी का आकार लेन (सरणी) है जो "गणना" नहीं है बल्कि सूची की विशेषता है। लूपिंग निश्चित रूप से [0] + = बी [0] ... [999] + = बी [99 9] से कम टाइपिंग है। कम त्रुटि-प्रवण भी। और भी स्पष्ट है। गलत टाइपिंग से त्रुटियों को रोकने के लिए मैं थोड़ा दक्षता छोड़ दूंगा। –

+0

मुझे लगता है कि मेरा मुख्य पकड़ एक सूची बना और वापस कर देगा, जो इस मामले में आवश्यक नहीं होगा। अन्यथा, हाँ, यह अन्य विचार से भी बदतर नहीं है। –

9

कैसे इस बारे में:

a = [x+y for x,y in zip(a,b)] 
+2

+1 लेकिन यह केवल तब काम करेगा जब सूचियां एक ही आकार के होंगी। 0 के ज़िप मूल्य के साथ izip_longest अगर वे हमेशा एक ही आकार –

+0

नाइस के नहीं हैं, लेकिन यह बहुत सारे टाइपिंग को सहेजता नहीं है, और मूल कोड तीन गुना तेज है। –

+0

@ kotlinski- hmm, आप सही हैं –

3

[एक [x] + बी [x] श्रेणी में एक्स के लिए (0, लेन (क))]

+0

यह वही है जो ओपी पहले से ही कर रहा है। – SilentGhost

+2

यह कम टाइपिंग संस्करण है, कृपया अपनी आलोचना में रचनात्मक बनें। आपकी अंधे आलोचना किसी की भी मदद नहीं कर रही है। – ismail

+1

यह न तो मानक है और न ही कुशल है। क्या यह आपके लिए पर्याप्त रचनात्मक है? – SilentGhost

29

आप कुशल वेक्टर गणित की जरूरत है, की कोशिश Numpy

>>> import numpy 
>>> a=numpy.array([0,1,2]) 
>>> b=numpy.array([3,4,5]) 
>>> a+b 
array([3, 5, 7]) 
>>> 

या (धन्यवाद, एंड्रयू जैफ्फ),

>>> a += b 
>>> a 
array([3, 5, 7]) 
>>> 
+0

एनबी। ओपी चाहता है एक + = बी, वास्तव में - नीचे मेरा जवाब देखें! ;-) –

+1

टाइपिंग को सहेजने का एक अच्छा तरीका प्रतीत होता है, लेकिन मुझे यह पसंद नहीं है कि यह एक निर्भरता जोड़ता है और मूल कोड से तीन गुना धीमा है। –

5

या, यदि आप एक बाहरी पुस्तकालय (और निश्चित लंबाई सरणियों) का उपयोग करने numpy, जो उपयोग करने को तैयार हैं "+ = "और इन-प्लेस ऑपरेशंस के लिए संबंधित संचालन।

import numpy as np 
a = np.array([0, 1, 2]) 
b = np.array([3, 4, 5]) 
a += b 
30

जबकि संख्यात्मक उत्कृष्ट है, और सूची-समझ समाधान ठीक करता है, तो आप वास्तव में एक नई सूची बनाना चाहता था, मुझे आश्चर्य कोई नहीं "यह करने के लिए एक स्पष्ट तरीका है" का सुझाव दिया है - एक सरल for पाश! बेस्ट:

for i, bi in enumerate(b): a[i] += bi 

भी ठीक है, थोड़े sorta: एक्स के लिए

for i in xrange(len(a)): a[i] += b[i] 
+0

+1, यह मेरे लिए स्पष्ट समाधान है। – Kiv

+1

अन्य समाधानों की तुलना में तेज़, लेकिन अभी भी तेज़ जितना तेज़ है। –

0

समझ सूची का एक सुधार (कम स्मृति की खपत)

आयात itertools एक = [x + y, वाई itertools.izip (ए, बी)]

असल में यदि आप सुनिश्चित नहीं हैं कि एक उपभोग का उपभोग होगा तो मैं जनरेटर अभिव्यक्ति के साथ भी जाऊंगा:

(x + y के लिए x, y itertools में y।izip (ए, बी))

13

अगर आपको लगता है Numpy overkill है, यह वास्तव में तेजी से, क्योंकि इस कोड शुद्ध सी (map() और __add__() दोनों सीधे सी में लागू किया जाता है) में चलता किया जाना चाहिए:

a = [1.0,2.0,3.0] 
b = [4.0,5.0,6.0] 

c = map(float.__add__, a, b) 

या वैकल्पिक रूप से, अगर आप सूची में प्रकार पता नहीं है:

import operator 
c = map(operator.add, a, b) 
+0

यह वास्तव में एक अच्छा जवाब है, लेकिन दुर्भाग्यवश मूल कोड से तीन गुना धीमा है। –

+0

यह वास्तव में मुझे suprises। कम से कम पहला संस्करण तेज होना चाहिए। यदि आपके पास बड़ी सूचियां हैं तो शायद यह तेज़ है। –

+3

ऑपरेटर मॉड्यूल पर एक नज़र डालें। आप बस 'operator.add' का उपयोग कर सकते हैं। – schlamar

1

यदि आप के एक जनरेटर संस्करण का उपयोग कर सकते हैं संक्षेप में, कोशिश करें ...

vectors = [[0.0, 1.0, 2.0],[3.0, 4.0, 5.0]] 
[sum(col) for col in zip(*vectors)] 

हालांकि मैं पी के लिए बात नहीं कर सकता इसका विकृति

0
list(map(lambda x:x[0]+x[1], zip(a,b))) 
+0

कहने की अनुमति देता है क्या आप इस समाधान को थोड़ा सा समझा सकते हैं? – dethtron5000

+0

ज़रूर :) सबसे पहले, मैंने ** ज़िप फ़ंक्शन ** लागू किया जो टुपल्स की एक सूची लौटाएगा, उदा। यदि 'ए = [1,2,3]' और 'बी = [4,5,6]', 'ज़िप (ए, बी)' रिटर्न '[(1,4), (2,5), (3 , 6)] '। इसके बाद, मैंने इस परिणाम में ** मैप ** लागू किया, ** मैप ** फ़ंक्शन पहला तर्क के रूप में एक फ़ंक्शन लेता है और दूसरे तर्क के रूप में एक पुनरावर्तनीय होता है और यह उस क्रिया को प्रत्येक पुनरावर्तनीय पर लागू करता है। इस मामले में, पुनरावर्तनीय 'ज़िप (ए, बी)' है और फ़ंक्शन 'लैम्ब्डा x: x [0] + x [1] 'है, यह एक आइटम' x' को तर्क के रूप में प्राप्त करता है और यह 'x [0 देता है ] + x [1] '। 'नक्शा()' python2 में एक सूची देता है। Python3 में यह एक नक्शा वस्तु देता है, इसलिए मैंने 'सूची() ' –

1

सूचियों की एक सूची होने आप कुछ इस तरह कर सकता है के सामान्य मामले के लिए:

In [2]: import numpy as np 

In [3]: a = np.array([[1, 1, 1], [2, 2, 2], [3, 3, 3],[4, 5, 6]]) 

In [4]: [sum(a[:,i]) for i in xrange(len(a[0]))] 
Out[4]: [10, 11, 12] 
संबंधित मुद्दे