2017-02-07 7 views
9

मैं एक मनमाने ढंग से तो जैसे iterable नेस्ट हैपायथन: पुनरावर्ती iterables पर एक समारोह मानचित्र

numbers = (1, 2, (3, (4, 5)), 7) 

और मैं संरचना को बदले बिना इस पर एक समारोह मैप करने के लिए करना चाहते हैं। उदाहरण के लिए, मैं

strings = recursive_map(str, numbers) 
assert strings == ('1', '2', ('3', ('4', '5')), '7') 

प्राप्त करने का कोई अच्छा तरीका है, तो मैं सभी संख्याओं को तारों में स्ट्रिंग में बदलना चाहता हूं। मैं numbers मैन्युअल रूप से ट्रैवर्स करने के लिए अपनी खुद की विधि लिखने की इमेजिंग कर सकता हूं, लेकिन मैं जानना चाहता हूं कि पुनरावर्ती पुनरावृत्तियों पर मानचित्रण करने का कोई सामान्य तरीका है या नहीं।

इसके अलावा, मेरे उदाहरण में, यह ठीक है अगर strings मुझे नेस्टेड सूचियों (या कुछ पुनरावृत्त) बल्कि नेस्टेड टुपल्स देता है।

उत्तर

10

हम अनुक्रम में हर तत्व को स्कैन, और गहरा प्रत्यावर्तन में आगे बढ़ता है, तो वर्तमान आइटम एक उप अनुक्रम है, या पैदावार यह मानचित्रण है अगर हम एक गैर अनुक्रम डेटा प्रकार पर पहुंच गया (int, str, या किसी भी जटिल हो सकता है वर्ग)।

हम collections.Sequence का उपयोग हर दृश्य के लिए विचार सामान्यीकरण करने के लिए, और न केवल tuples या सूचियों, और उपज पर type(item) सुनिश्चित करने के लिए है कि उप दृश्यों हम एक ही प्रकार वे थे के अवशेष वापस मिलता है।

from collections import Sequence 

def recursive_map (seq, func): 
    for item in seq: 
     if isinstance(item, Sequence): 
      yield type(item)(recursive_map(item, func)) 
     else: 
      yield func(item) 

डेमो:

>>> numbers = (1, 2, (3, (4, 5)), 7) 
>>> mapped = recursive_map(numbers, str) 
>>> tuple(mapped) 
('1', '2', ('3', ('4', '5')), '7') 

या एक अधिक जटिल उदाहरण:

>>> complex_list = (1, 2, [3, (complex('4+2j'), 5)], map(str, (range(7, 10)))) 
>>> tuple(recursive_map(complex_list, lambda x: x.__class__.__name__)) 
('int', 'int', ['int', ('complex', 'int')], 'map') 
+1

कृपया अपने कोड की व्याख्या। –

+0

मेरा मानना ​​है कि आप केवल * अनुक्रम * के लिए सामान्यीकृत हैं। चाहे कुछ पुनरावर्तनीय है, प्रकार का मुद्दा नहीं है लेकिन प्रोटोकॉल का पालन करना है। ओपी का अर्थ अनुक्रम हो सकता है, लेकिन यह सेट, नलिकाओं आदि पर पुनरावृत्ति नहीं करेगा। चाहे किसी चीज को पुनरावृत्त किया गया हो या नहीं, यह परिभाषित किया गया है कि यह पुनरावर्तनीय प्रोटोकॉल –

+0

@ जुआनपा.र्रिविल्लागा धन्यवाद! अद्यतन अर्थशास्त्र – Uriel

6
def recursive_map(f, it): 
    return (recursive_map(f, x) if isinstance(x, tuple) else f(x) for x in it) 
0

आप dict, set और दूसरों के लिए, आप ऊरीएल का उपयोग कर सकते हैं अपने परिणाम का विस्तार करना चाहते हैं उत्तर:

from collections import Sequence, Mapping 

def recursive_map(data, func): 
    apply = lambda x: recursive_map(x, func) 
    if isinstance(data, Mapping): 
     return type(data)({k: apply(v) for k, v in data.items()}) 
    elif isinstance(data, Sequence): 
     return type(data)(apply(v) for v in data) 
    else: 
     return func(data) 

टेस्ट इनपुट:

recursive_map({0: [1, {2, 2, 3}]}, str) 

पैदावार:

{0: ['1', '{2, 3}']} 
संबंधित मुद्दे