2016-03-08 7 views
5

मेरे पास 2 डी डेटा है जिसे मैं एकाधिक फ़ंक्शन लागू करना चाहता हूं। वास्तविक कोड xlrd और .xlsx फ़ाइल का उपयोग करता है, लेकिन मैं निम्नलिखित बॉयलर प्लेट प्रदान करूंगा ताकि आउटपुट पुन: उत्पन्न करना आसान हो।मानचित्र के साथ कई फ़ंक्शंस लागू करें

class Data: 
    def __init__(self, value): 
     self.value = value 

class Sheet: 
    def __init__(self, data): 
     self.data = [[Data(value) for value in row.split(',')] for row in data.split('\n')] 
     self.ncols = max(len(row) for row in self.data) 

    def col(self, index): 
     return [row[index] for row in self.data] 

एक शीट बनाना:

fake_data = '''a, b, c, 
       1, 2, 3, 4 
       e, f, g, 
       5, 6, i, 
       , 6, , 
       , , , ''' 

sheet = Sheet(fake_data) 

इस वस्तु में, data तार के एक 2D सरणी (इनपुट प्रारूप के अनुसार) शामिल हैं और मैं इस वस्तु के स्तंभों पर कार्रवाई करने के लिए चाहते हैं। इस बिंदु पर कुछ भी मेरे नियंत्रण में नहीं है।

मैं इस संरचना करने के लिए तीन बातें करना चाहता हूँ:, स्तंभों में पंक्तियों स्थानांतरित प्रत्येक Data वस्तु से value निकालने, और एक float के लिए मूल्य बदलने की कोशिश। यदि मान float नहीं है, तो इसे str में विभाजित सफेद-स्थान के साथ परिवर्तित किया जाना चाहिए।

from operators import attrgetter 

# helper function 
def parse_value(value): 
    try: 
     return float(value) 
    except ValueError: 
     return str(value).strip() 

# transpose 
raw_cols = map(sheet.col, range(sheet.ncols)) 

# extract values 
value_cols = (map(attrgetter('value'), col) for col in raw_cols) 

# convert values 
typed_cols = (map(parse_value, col) for col in value_cols) 

# ['a', 1.0, 'e', 5.0, '', ''] 
# ['b', 2.0, 'f', 6.0, 6.0, ''] 
# ['c', 3.0, 'g', 'i', '', ''] 
# ['', 4.0, '', '', '', ''] 

यह देखा जा सकता है कि map दो बार प्रत्येक स्तंभ के लिए लागू किया जाता है। अन्य परिस्थितियों में, मैं प्रत्येक कॉलम में दो बार से अधिक फ़ंक्शन लागू करना चाहता हूं।

क्या पुनरावृत्तियों की प्रविष्टियों में एकाधिक कार्यों को मैप करने का बेहतर तरीका है? अधिक से अधिक, जेनरेटर समझ से बचने के लिए दूर है और सीधे प्रत्येक आंतरिक-मैप करने योग्य मैपिंग लागू करता है? या, क्या यह सब एक साथ पहुंचने का एक बेहतर और एक्स्टेंसिबल तरीका है?

ध्यान दें कि यह प्रश्न xlrd के लिए विशिष्ट नहीं है, यह केवल वर्तमान उपयोग-मामला है।

+0

अनुस्मारक: 'नक्शा (च, नक्शे (छ, XS))' (, XS रचना (च, छ)) 'के रूप में नक्शे में एक ही उत्पादन है'; पूर्व दो बार संग्रह के माध्यम से फिर से शुरू होगा, लेकिन बाद में केवल एक बार फिर से शुरू होगा। – naomik

+0

@ नोमिक राइट, मैं बस चाहता हूं कि मुझे लगता है कि 'compose' अंतर्निहित था। –

+1

जेरेड, आप आसानी से अपना खुद का बना सकते हैं। 'compose'' lambda f से अधिक कुछ नहीं है, g: lamda x: f (g (x)) '। या बस 'मानचित्र का उपयोग करें (लैम्ब्डा एक्स: एफ (जी (एक्स)), एक्सएस) ' – naomik

उत्तर

2

ऐसा प्रतीत होता है कि सबसे आसान समाधान अपने स्वयं के फ़ंक्शन को रोल करना है जो एक ही पुनरावर्तनीय पर कई फ़ंक्शन लागू करेगा।

def map_many(iterable, function, *other): 
    if other: 
     return map_many(map(function, iterable), *other) 
    return map(function, iterable) 

नकारात्मक पक्ष यह है कि यहाँ उपयोग map(function, iterable) से उलट है और यह map विस्तार करने के लिए (अजगर 3.x में है जैसे कि यह कर सकते हैं) तर्क स्वीकार करने के लिए अजीब हो जाएगा है।

उपयोग:

map_many([0, 1, 2, 3, 4], str, lambda s: s + '0', int) 
# [0, 10, 20, 30, 40] 
4

आप आसानी से क्लब पिछले दो map एक lambda,

typed_cols = (map(lambda element:parse_value(element['value']), col) 
       for col in value_cols) 

का उपयोग करके कॉल आप पार्स में इसी तरह की छड़ी और Sheet.col अंदर निकालने, IMO कि कोड की पठनीयता को प्रभावित करती है सकते हैं कर सकते हैं।

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