2 सूचियों का तत्व-वार जोड़?


244

अब मेरे पास है:

list1 = [1, 2, 3]
list2 = [4, 5, 6]

मेरी इच्छा है:

[1, 2, 3]
 +  +  +
[4, 5, 6]
|| || ||
[5, 7, 9]

बस दो सूचियों का एक तत्व-वार जोड़।

मैं निश्चित रूप से दो सूचियों को पुनरावृत्त कर सकता हूं, लेकिन मैं ऐसा नहीं करना चाहता।

ऐसा करने का सबसे पाइथोनिक तरीका क्या है?


जवाबों:


364

के mapसाथ प्रयोग करें operator.add:

>>> from operator import add
>>> list( map(add, list1, list2) )
[5, 7, 9]

या zipसूची की समझ के साथ:

>>> [sum(x) for x in zip(list1, list2)]
[5, 7, 9]

समय की तुलना:

>>> list2 = [4, 5, 6]*10**5
>>> list1 = [1, 2, 3]*10**5
>>> %timeit from operator import add;map(add, list1, list2)
10 loops, best of 3: 44.6 ms per loop
>>> %timeit from itertools import izip; [a + b for a, b in izip(list1, list2)]
10 loops, best of 3: 71 ms per loop
>>> %timeit [a + b for a, b in zip(list1, list2)]
10 loops, best of 3: 112 ms per loop
>>> %timeit from itertools import izip;[sum(x) for x in izip(list1, list2)]
1 loops, best of 3: 139 ms per loop
>>> %timeit [sum(x) for x in zip(list1, list2)]
1 loops, best of 3: 177 ms per loop

10
यदि आप उन विशाल सरणियों का उपयोग करते हैं, तो @BasSwinckels द्वारा संख्यात्मक समाधान शायद कुछ ऐसा है जिसे आपको देखना चाहिए।
हेनरी गोमर्सल

1
उन समयों के लिए आपने पायथन संस्करण का क्या उपयोग किया?
अर्शजी

9
NB - python3 में, मानचित्र () सूची के बजाय एक पुनरावृत्ति योग्य वस्तु देता है। यदि आपको वास्तविक सूची की आवश्यकता है, तो पहला उत्तर सूची है (मानचित्र (जोड़ें, सूची 1, सूची 2))
FLHerne

@ FHerne के साथ नोट किए गए python3 के मुद्दे पर ध्यान देना समय के साथ mapऔर अधिक महत्वपूर्ण हो जाएगा। पायथन 2 को 3 साल से भी कम समय में आधिकारिक समर्थन मिल जाएगा।
nealmcb

1
ऐसे कई बार हैं, जहां अजगर वाक्यविन्यास वास्तव में सुरुचिपूर्ण और सरल है, लेकिन दुर्भाग्य से यह उनमें से एक नहीं है। और इस तरह के एक सरल कार्य के लिए, यह अफ़सोस की बात है .... जब वे पहले से ही .extend () विधि है तो वे सूची को "+" क्यों बनाएंगे?
निक स्कोज़ज़ारो

105

दूसरों ने उदाहरण दिया कि शुद्ध अजगर में यह कैसे किया जाए। यदि आप 100.000 तत्वों के साथ सरणियों के साथ ऐसा करना चाहते हैं, तो आपको numpy का उपयोग करना चाहिए:

In [1]: import numpy as np
In [2]: vector1 = np.array([1, 2, 3])
In [3]: vector2 = np.array([4, 5, 6])

तत्व-वार जोड़ को करना अब उतना ही तुच्छ है

In [4]: sum_vector = vector1 + vector2
In [5]: print sum_vector
[5 7 9]

जैसे मतलाब में।

अश्विनी के सबसे तेज़ संस्करण के साथ तुलना करने का समय:

In [16]: from operator import add
In [17]: n = 10**5
In [18]: vector2 = np.tile([4,5,6], n)
In [19]: vector1 = np.tile([1,2,3], n)
In [20]: list1 = [1,2,3]*n
In [21]: list2 = [4,5,6]*n
In [22]: timeit map(add, list1, list2)
10 loops, best of 3: 26.9 ms per loop

In [23]: timeit vector1 + vector2
1000 loops, best of 3: 1.06 ms per loop

तो यह एक कारक है 25 तेजी से! लेकिन जो आपकी स्थिति के अनुकूल है उसका उपयोग करें। एक साधारण कार्यक्रम के लिए, आप शायद सुन्न को स्थापित नहीं करना चाहते हैं, इसलिए मानक अजगर का उपयोग करें (और मुझे हेनरी का संस्करण सबसे पाइथोनिक एक लगता है)। यदि आप गंभीर संख्या में क्रंचिंग कर रहे हैं, तो numpyभारी लिफ्टिंग करें। गति शैतान के लिए: ऐसा लगता है कि सुन्न समाधान तेजी से चारों ओर शुरू हो रहा है n = 8


59
[a + b for a, b in zip(list1, list2)]

4
@deltab स्वीकृत उत्तर तेज़ है और इसमें यह उत्तर (अधिक जानकारीपूर्ण) है
सिब्ब्स जुआ

2
@ perfectionm1ng हालांकि मैं आपकी बात को समझता हूं (और इसे एक बार भी नहीं समझा जा सकता) मुझे लगा कि यह इस ओर इशारा करने लायक है कि मैं हमेशा अपने द्वारा प्रस्तुत समाधान का उपयोग करूंगा (जिसे इसके लिए कोई आयात की आवश्यकता नहीं है, यकीनन सबसे सरल है, साथ ही साथ के रूप में यकीनन अधिक pythonic), या जहां गति मायने रखती है , बास स्विनकेल का जवाब , जो कि सही विकल्प है जहां गति मायने रखती है।
हेनरी गोमरसेल

हाँ। राय के लिए धन्यवाद। लेकिन अनिवार्य [sum(x) for x in zip(list1, list2)]रूप से आपके उत्तर के समान ही है, है ना? :)
Sibbs जुआ

4
@ perfectionm1ng कम या ज्यादा (हालांकि यह एक संपादित के साथ खान के बाद जोड़ा गया था :)। व्यक्तिगत रूप से, मैं पठनीयता और pythonicness के लिए स्पष्ट tuple unpacking के साथ a + b संकेतन को प्राथमिकता देता हूं।
हेनरी गोमरसेल

12

जैसा कि अन्य लोगों द्वारा बताया गया है, एक तेज और भी अंतरिक्ष कुशल समाधान सुव्यवस्थित (एनपी) का उपयोग कर रहा है, यह अंतर्निहित वेक्टर हेरफेर क्षमता के साथ है:

1. Numpy के साथ

x = np.array([1,2,3])
y = np.array([2,3,4])
print x+y

2. बिल्ट-इन के साथ

२.१ लमबा

list1=[1, 2, 3]
list2=[4, 5, 6]
print map(lambda x,y:x+y, list1, list2)

ध्यान दें कि मानचित्र () कई तर्कों का समर्थन करता है।

2.2 ज़िप और सूची समझ

list1=[1, 2, 3]
list2=[4, 5, 6]
print [x + y for x, y in zip(list1, list2)]

1
लैम्ब्डा दृष्टिकोण के लिए +1। यह शर्म की बात है कि यह समाधान अन्य समाधानों के साथ संयुक्त है जो कहीं और नकल कर रहे हैं।
लंदनरोब

10

यह numpyमेरी राय से उपयोग करने के लिए आसान है :

import numpy as np
list1=[1,2,3]
list2=[4,5,6]
np.add(list1,list2)

परिणाम:

टर्मिनल निष्पादन

विस्तृत पैरामीटर जानकारी के लिए, यहाँ देखें: numpy.add


6

शायद "सबसे पायथोनिक तरीका" में उस मामले को संभालना शामिल होना चाहिए जहां list1 और list2 समान आकार नहीं हैं। इनमें से कुछ तरीकों को लागू करने से आपको चुपचाप जवाब मिल जाएगा। संख्यात्मक दृष्टिकोण आपको बताएगा, सबसे अधिक संभावना है एक ValueError के साथ।

उदाहरण:

import numpy as np
>>> list1 = [ 1, 2 ]
>>> list2 = [ 1, 2, 3]
>>> list3 = [ 1 ]
>>> [a + b for a, b in zip(list1, list2)]
[2, 4]
>>> [a + b for a, b in zip(list1, list3)]
[2]
>>> a = np.array (list1)
>>> b = np.array (list2)
>>> a+b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (2) (3)

यदि आप अपनी समस्या में एक समारोह में थे तो आप कौन सा परिणाम चाहते हैं?


इस मामले में निश्चित रूप zip_longestसे एक fillvalueके साथ itertools से देखना चाहिए 0
Ma0


5

यह 2 या अधिक सूचियों के लिए काम करेगा; सूचियों की सूची के माध्यम से पुनरावृत्ति, लेकिन प्रत्येक सूची के तत्वों से निपटने के लिए संख्यात्मक जोड़ का उपयोग करना

import numpy as np
list1=[1, 2, 3]
list2=[4, 5, 6]

lists = [list1, list2]
list_sum = np.zeros(len(list1))
for i in lists:
   list_sum += i
list_sum = list_sum.tolist()    

[5.0, 7.0, 9.0]

5

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

जब तक सूचियां समान लंबाई की हैं, तब तक आप नीचे दिए गए फ़ंक्शन का उपयोग कर सकते हैं।

यहाँ * args सूची तर्कों की एक चर संख्या को स्वीकार करता है (लेकिन केवल प्रत्येक में समान संख्या में तत्वों को शामिल करता है)।

* प्रत्येक सूची में तत्वों को अनपैक करने के लिए लौटी सूची में फिर से उपयोग किया जाता है।

def sum_lists(*args):
    return list(map(sum, zip(*args)))

a = [1,2,3]
b = [1,2,3]  

sum_lists(a,b)

आउटपुट:

[2, 4, 6]

या 3 सूचियों के साथ

sum_lists([5,5,5,5,5], [10,10,10,10,10], [4,4,4,4,4])

आउटपुट:

[19, 19, 19, 19, 19]

3

लैम्ब्डा फ़ंक्शन के साथ मानचित्र का उपयोग करें:

>>> map(lambda x, y: x + y, list1, list2)
[5, 7, 9]

3

मैंने इसे समयबद्ध नहीं किया है लेकिन मुझे संदेह है कि यह बहुत जल्दी होगा:

import numpy as np
list1=[1, 2, 3]
list2=[4, 5, 6]

list_sum = (np.add(list1, list2)).tolist()

[5, 7, 9]

3

यदि आपको विभिन्न आकारों की सूचियों को संभालने की आवश्यकता है, तो चिंता न करें! अद्भुत itertools मॉड्यूल आप को कवर किया है:

>>> from itertools import zip_longest
>>> list1 = [1,2,1]
>>> list2 = [2,1,2,3]
>>> [sum(x) for x in zip_longest(list1, list2, fillvalue=0)]
[3, 3, 3, 3]
>>>

अजगर 2 में, zip_longestकहा जाता है izip_longest

इस प्रासंगिक उत्तर को भी देखें और एक अन्य प्रश्न पर टिप्पणी करें



2

हालाँकि, वास्तविक प्रश्न परिणाम उत्पन्न करने के लिए सूची पर पुनरावृति नहीं करना चाहता है, लेकिन प्रस्तावित किए गए सभी समाधान हूड के नीचे बिल्कुल सटीक है!

ताज़ा करने के लिए: आप सभी वेक्टर तत्वों को देखे बिना दो वैक्टर नहीं जोड़ सकते। तो, इनमें से अधिकांश समाधानों की एल्गोरिथम जटिलता बिग-ओ (एन) है। जहाँ n वेक्टर का आयाम है।

इसलिए, एल्गोरिथम के दृष्टिकोण से, लूप के लिए पुनरावृत्त करने के लिए परिणामी सूची उत्पन्न करना तार्किक और पाइथोनिक भी है। हालाँकि, इसके अतिरिक्त, इस पद्धति में किसी अतिरिक्त लाइब्रेरी को कॉल करने या आयात करने का ओवरहेड नहीं है।

# Assumption: The lists are of equal length.
resultList = [list1[i] + list2[i] for i in range(len(list1))]

यहां दिखाए / चर्चा किए गए समय प्रणाली और कार्यान्वयन पर निर्भर हैं, और ऑपरेशन की दक्षता को मापने के लिए विश्वसनीय उपाय नहीं हो सकते हैं। किसी भी मामले में, वेक्टर जोड़ ऑपरेशन की बड़ी ओ जटिलता रैखिक है, जिसका अर्थ हे (एन) है।


1
a_list = []
b_list = []
for i in range(1,100):
    a_list.append(random.randint(1,100))

for i in range(1,100):
    a_list.append(random.randint(101,200))
[sum(x) for x in zip(a_list , b_list )]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.