2010-07-09 15 views
99

मैं इस कोड के लिए निम्न कोडपायथन में दो जेनरेटर कैसे शामिल हों?

for directory, dirs, files in os.walk(directory_1): 
    do_something() 

for directory, dirs, files in os.walk(directory_2): 
    do_something() 

बदलना चाहते हैं:

unsupported operand type(s) for +: 'generator' and 'generator'

कैसे पायथन में दो जनरेटर शामिल होने के लिए:

for directory, dirs, files in os.walk(directory_1) + os.walk(directory_2): 
    do_something() 

मैं त्रुटि मिलती है?

+1

मैं भी अजगर की तरह इस तरह से काम करने के लिए चाहते हैं। बिल्कुल एक ही त्रुटि मिल गई! –

उत्तर

141

मुझे लगता है कि itertools.chain() इसे करना चाहिए।

+1

http://docs.python.org/library/itertools.html – reto

+3

हां, यह ठीक है 'चेन() ' –

+16

के लिए है, जब' itertools.chain' का उपयोग करते हुए दो पुनरावृत्तियों को जोड़ने के लिए, प्रश्न में, लेकिन सभी पुनरावृत्तियों में एक पुनरावृत्त (उदाहरण के लिए, 'श्रृंखला (* imap (xrange, xrange (5)))'), आप [पायथन बग # 4806] (http://bugs.python.org/issue4806) में भाग सकते हैं, जो मास्क किसी भी TypeError को पुन: प्रयोज्य के भीतर उठाया गया है और एक भ्रमित त्रुटि संदेश की ओर जाता है। वैकल्पिक रूप से, आप उस मामले में 'itertools.chain.from_iterable' (पायथन 2.6 के बाद से) का उपयोग कर सकते हैं, जो सीधे तर्क के रूप में पुनरावृत्तियों को पुन: लेता है: 'chain.from_iterable (imap (xrange, xrange (5)))'। –

29

कोड का एक उदाहरण:

from itertools import chain 

def generator1(): 
    for item in 'abcdef': 
     yield item 

def generator2(): 
    for item in '123456': 
     yield item 

generator3 = chain(generator1(), generator2()) 
for item in generator3: 
    print item 
5
itertools.chain.from_iterable साथ

आप की तरह कर सकते हैं:

def genny(start): 
    for x in range(start, start+3): 
    yield x 

y = [1, 2] 
ab = [o for o in itertools.chain.from_iterable(genny(x) for x in y)] 
print(ab) 
1

सरल उदाहरण:

from itertools import chain 
x = iter([1,2,3])  #Create Generator Object (listiterator) 
y = iter([3,4,5])  #another one 
result = chain(x, y) #Chained x and y 
0

आप रखना चाहते हैं जेनरेटर अलग होते हैं लेकिन फिर भी उन पर फिर से सक्रिय होते हैं, आप ज़िप():

का उपयोग कर सकते हैं

नोट: पुनरावृत्ति दो जनरेटर

उदाहरण के लिए के छोटे पर रुक जाता है:

for (root1, dir1, files1), (root2, dir2, files2) in zip(os.walk(path1), os.walk(path2)): 

    for file in files1: 
     #do something with first list of files 

    for file in files2: 
     #do something with second list of files 
0

कहते हैं कि हम जनरेटर (Gen1 और जनरल 2) करने के लिए है कि चलें और हम कुछ अतिरिक्त परिकलन करना चाहते हैं कि दोनों के नतीजे की आवश्यकता है। हम मानचित्र विधि के माध्यम से इस तरह के फ़ंक्शन/गणना के परिणाम वापस कर सकते हैं, जो बदले में जनरेटर लौटाता है जिसे हम लूप कर सकते हैं।

इस परिदृश्य में, कार्य/गणना को लैम्ब्डा फ़ंक्शन के माध्यम से कार्यान्वित करने की आवश्यकता है। मुश्किल भाग वह है जिसे हम मानचित्र और उसके लैम्ब्डा फ़ंक्शन के अंदर करना चाहते हैं।

प्रस्तावित समाधान के जनरल प्रपत्र:

def function(gen1,gen2): 
     for item in map(lambda x, y: do_somethin(x,y), gen1, gen2): 
      yield item 
+2

में तय किया गया है आपको कोड के ब्लॉक के बजाय यह क्या करना चाहिए इसके बारे में कुछ उपयोगी स्पष्टीकरण पोस्ट करना चाहिए – AK47

1

में python3 + आप कर सकते हैं:

def concat(a, b): 
    yield from a 
    yield from b 
संबंधित मुद्दे