2013-01-12 9 views
15

अगर मैं दो सरणियों, एक ही लंबाई की है - कहते हैं कि a और bएक ही समय में दो सरणी के माध्यम से लूप करने के लिए पाइथोनिक तरीका क्या है?

a = [4,6,2,6,7,3,6,7,2,5]

b = [6,4,6,3,2,7,8,5,3,5]

सामान्य रूप से, मैं इतना है कि यह करना होगा:

for i in range(len(a)): 
    print a[i] + b[i] 
कुछ

बजाय इस तरह:

i=0 
for number in a: 
    print number + b[i] 
    i += 1 

क्योंकि मैं प्रयुक्त विधियों के अनुरूप होना पसंद करता हूं।

मुझे zip पता है, लेकिन मैंने इसका कभी भी उपयोग नहीं किया। क्या यह zip के लिए बनाया गया था?

for pair in zip(a,b): 
    print pair[0] + pair[1] 

pythonic तरीका यह है हो सकता है?

उत्तर

17

सूचियों a और b कम कर रहे हैं, zip का उपयोग करते हैं (जैसा कि @Vincenzo Pii से पता चला है):

for x, y in zip(a, b): 
    print(x + y) 

सूचियों a और b लंबे होते हैं, तो itertools.izip का उपयोग स्मृति को बचाने के लिए:

import itertools as IT 
for x, y in IT.izip(a, b): 
    print(x + y) 

zip टुपल्स की एक सूची बनाता है। यह a और b बड़े होने पर बोझिल (स्मृति-वार) हो सकता है।

itertools.izip एक पुनरावर्तक देता है। इटेटरेटर टुपल्स की पूरी सूची उत्पन्न नहीं करता है; यह केवल प्रत्येक आइटम को उपज करता है क्योंकि इसे फॉर-लूप द्वारा अनुरोध किया जाता है। इस प्रकार यह आपको कुछ स्मृति बचा सकता है।

छोटी सूची में zip(a,b) पर पायथन 2 कॉलिंग itertools.izip(a,b) का उपयोग करने से तेज़ है। लेकिन पायथन 3 में ध्यान दें कि zip डिफ़ॉल्ट रूप से एक इटरेटर लौटाता है (यानी यह Python2 में itertools.izip के बराबर है)।


हित के अन्य प्रकारों:

  • from future_builtin import zip - अगर आप python3 शैली को Python2 में zip जबकि साथ प्रोग्राम करना चाहते हैं।
  • itertools.izip_longest - यदि a और b असमान लंबाई के हैं।
+1

इसे पूरा करने के लिए, मैं 'future_builtins' का भी उल्लेख करूंगा। – georg

+0

तो python3 में ज़िप में itertools.izip जैसा ही है? या यह सूचियों के आकार के आधार पर बदलता है? – will

+2

@ विल्ल: हाँ, पायथन 3 में 'ज़िप' Python2 में 'itertools.izip' जैसा ही है। (यह सूची के आकार के साथ व्यवहार नहीं बदलता है।) पायथन 3 में पुराना 'ज़िप' व्यवहार प्राप्त करने के लिए, 'सूची (ज़िप (ए, बी))' का उपयोग करें। – unutbu

7

सम्भावित समाधान zip उपयोग कर रहा है, के रूप में आप अपने आप को उल्लेख किया है, लेकिन से आप इसे कैसे सवाल में लिखा है कुछ अलग ढंग से:

for x, y in zip(a, b): 
    print x, y 

सूचना है कि zip() द्वारा दिया tuples की सूची की लंबाई बराबर हो जाएगा a और b की लंबाई के बीच न्यूनतम तक। यह तब प्रभावित होता है जब a और b समान लंबाई के नहीं होते हैं।

+0

यह बहुत परिचित दिखता है: दृश्यों "छेद" उस में, itertools.zip_longest का उपयोग छेद को भरने के लिए (भरण मूल्य चूक None के लिए, लेकिन निर्दिष्ट किया जा सकता है) विभिन्न उदाहरणों और दस्तावेज़ीकरण पृष्ठों से – will

+0

यह पुष्टि करता है कि यह पाइथनिक है :)! –

4

zip का उपयोग करने के बजाय आप Numpy का उपयोग कर सकते हैं, खासकर यदि गति महत्वपूर्ण है और आपके पास लंबे सरणी हैं। इसकी बहुत तेजी से और आप NumPy सरणी का उपयोग कर रहे एक बार आप एक पाश की आवश्यकता नहीं है, और बस लिख सकते हैं:

print a + b 

ग्राफ दिखा रहा है अलग लंबाई ज़िप, izip, और numpy का उपयोग करके सूचियां संक्षेप के लिए समय औसतन: enter image description here

+1

याहू मुझे numpy के बारे में पता है। यह निश्चित रूप से इस उदाहरण में लागू है, लेकिन मैंने जो उदाहरण दिया वह सिर्फ एक प्रसंस्कृत था। जब मैं ऑब्जेक्ट्स की दो सूचियां रखता हूं, तो मैं वास्तव में यह चाहता हूं कि आप दोनों की एनएच ऑब्जेक्ट एक्सेस करना चाहते हैं। यह मेरे लिए स्पष्ट हो गया जब मैं 'matplotlib' piechart में 'wedges'' के लिए 'हैच' पैटर्न जोड़ना चाहता था। अंत उपयोग कुछ पैटर्न के लिए होगा, ज़िप में पैटर्न (पैटर्न, wedges): wedge.set_hatch (पैटर्न) ' – will

0

numpy के बाद से पूर्णता के लिए यह उत्तर देने पर उत्तर दिया गया है, और अक्सर उच्च रैंक वाले सरणी से मूल्यों को जोड़ना उपयोगी होता है।

accepted answer रैंक 1. के किसी भी क्रम/सरणी के लिए अच्छा काम करता है हालांकि, अगर अनुक्रम एक list की list रों में के रूप में ऐसी ऐसी रैंक 2 या अधिक की एक numpy सरणी के रूप में कई स्तरों (की है, लेकिन यह भी, या tupletuple एस), प्रत्येक को प्रत्येक रैंक के माध्यम से फिर से शुरू करने की जरूरत है।

import numpy as np 
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) 
b = np.array([list('abc'), list('pdq'), list('xyz')]) 
c = np.array([[frobnicate(aval, bval) for aval, bval in zip(arow, brow)] for arow, brow in zip(a, b)]) 

और इसी अवधारणा एक ही आकार के दो आयामी नेस्टेड दृश्यों के किसी सेट के लिए काम करेंगे: नीचे एक 2 डी numpy सरणी के साथ एक उदाहरण है

a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 
b = [list('abc'), list('pdq'), list('xyz')] 
c = [[frobnicate(aval, bval) for aval, bval in zip(arow, brow)] for arow, brow in zip(a, b)] 

यदि एक या नेस्टेड के दोनों

from itertools import zip_longest as zipl 
a = [[], [4, 5, 6], [7, 8, 9]] # empty list in the first row 
b = [list('abc'), list('pdq'), []] # empty list in the last row 
c = [[frobnicate(aval, bval) for aval, bval in zipl(arow, brow)] for arow, brow in zipl(a, b)] 
संबंधित मुद्दे

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