2010-09-19 16 views
5

इस है कि मैं C++ करना होगा करने के लिए एक pythonic पसंदीदा तरीका है:pythonic तरीका अगर बयान


for s in str: 
    if r = regex.match(s): 
     print r.groups() 

मैं वास्तव में है कि वाक्य रचना की तरह, imo यह अस्थायी होने की तुलना में बहुत क्लीनर है हर जगह चर। एकमात्र अन्य तरीका जो अत्यधिक जटिल नहीं है


for s in str: 
    r = regex.match(s) 
    if r: 
     print r.groups() 

मुझे लगता है कि मैं एक सुंदर pedantic मुद्दे के बारे में शिकायत कर रहा हूं। मैं बस पूर्व वाक्यविन्यास याद आती है।

+1

'str' पायथन में एक अंतर्निहित प्रकार है इसलिए चर नामों के लिए उपयोग से बचा जाना चाहिए। – martineau

उत्तर

10

कैसे

for r in [regex.match(s) for s in str]: 
    if r: 
     print r.groups() 

या के बारे में थोड़ा अधिक कार्यात्मक

for r in filter(None, map(regex.match, str)): 
    print r.groups() 
+1

मुझे दूसरा संस्करण पसंद है। पहला संस्करण जनरेटर अभिव्यक्ति के साथ सूची समझ को प्रतिस्थापित कर सकता है, इसलिए यदि आप लूप से बाहर निकलते हैं तो यह केवल उन मैचों को ही करेगा जो आपको उस बिंदु तक की आवश्यकता होती है, बजाय उन्हें पहले सब कुछ करने के बजाय उन्हें लूप करना। –

+0

मुझे यह पसंद है। यह सबसे सीधे आगे लगता है। और सूची समझ पाइथन – Falmarri

1

असाइनमेंट अभिव्यक्ति करने के लिए recipe है लेकिन यह बहुत हैकी है। आपका पहला विकल्प संकलित नहीं करता है, इसलिए आपका दूसरा विकल्प जाने का तरीका है।

## {{{ http://code.activestate.com/recipes/202234/ (r2) 
import sys 
def set(**kw): 
    assert len(kw)==1 

    a = sys._getframe(1) 
    a.f_locals.update(kw) 
    return kw.values()[0] 

# 
# sample 
# 

A=range(10) 

while set(x=A.pop()): 
    print x 
## end of http://code.activestate.com/recipes/202234/ }}} 

आप देख सकते हैं, उत्पादन कोड एक दस फुट, डबल जीता छड़ी के साथ इस हैक नहीं छूना चाहिए।

1

यह एक बेहद साधारण जवाब हो सकता है, लेकिन आप इस पर विचार करेंगे:

for s in str: 
    if regex.match(s): 
     print regex.match(s).groups() 
+3

प्रदर्शन के लिए, आप कभी भी फ़ंक्शन कॉल को दोहराना नहीं चाहते हैं। अस्थायी असाइन करने के लिए अतिरिक्त लाइन क्लंकी लग सकती है, लेकिन इसका उद्देश्य है। – smci

+0

+1 क्योंकि कभी-कभी सादगी इसके लायक है; लेकिन यह केवल उस प्रदर्शन का नहीं है जिसे आप यहां खो रहे हैं, आप भी DRY का उल्लंघन कर रहे हैं - इस तरह के कोड को रेफैक्टर करना कठिन होता है और लंबे समय तक अधिक बग प्रवण होता है - उदाहरण के लिए, (बुराई) साइड इफेक्ट्स या कोड ब्लोट पर विचार करें जो आखिरकार छुपा सकता है समरूपता। –

1

कुछ है कि pythonic नहीं है करने के लिए कोई pythonic तरीका नहीं है। यह एक कारण के लिए है, क्योंकि 1, अगर किसी कथन के सशर्त हिस्से में बयान देने की अनुमति देता है तो व्याकरण बहुत बदसूरत हो जाएगा, उदाहरण के लिए, यदि आप शर्तों में असाइनमेंट स्टेटमेंट की अनुमति देते हैं, तो बयान क्यों न दें? आप वास्तव में इसे कैसे लिखेंगे? सी भाषाओं की तरह इस समस्या नहीं है, क्योंकि उनके पास असाइनमेंट स्टेटमेंट नहीं हैं। वे केवल असाइनमेंट एक्सप्रेशन और एक्सप्रेशन कथन के साथ करते हैं।

दूसरा कारण है क्योंकि जिस तरह से

if foo = bar: 
    pass 

बहुत

if foo == bar: 
    pass 

के लिए इसी तरह भले ही आप काफी चालाक सही टाइप करने के लिए, और यहां तक ​​कि अधिकांश सदस्य पर अगर कर रहे हैं लग रहा है की है आपकी टीम इसे ध्यान में रखने के लिए पर्याप्त तेज है, क्या आप निश्चित हैं कि जिस पर आप अभी देख रहे हैं वह वही है जो वहां होना चाहिए? यह देखने के लिए एक नए देव के लिए अनुचित नहीं है और इसे ठीक करें (एक तरफ या दूसरा) और अब यह निश्चित रूप से गलत है।

2

शायद यह थोड़ा hacky है, लेकिन एक समारोह वस्तु की विशेषताओं का उपयोग अंतिम परिणाम स्टोर करने के लिए आप इन पंक्तियों के साथ कुछ करने के लिए अनुमति देता है :

def fn(regex, s): 
    fn.match = regex.match(s) # save result 
    return fn.match 

for s in strings: 
    if fn(regex, s): 
     print fn.match.groups() 

या अधिक सामान्य रूप से:

def cache(value): 
    cache.value = value 
    return value 

for s in strings: 
    if cache(regex.match(s)): 
     print cache.value.groups() 

ध्यान दें कि हालांकि "मूल्य" बचाया चीजों के एक नंबर का एक संग्रह किया जा सकता है, इस दृष्टिकोण केवल एक ही इस तरह के एक बार में पकड़े हुए, तो एक से अधिक कार्य स्थितियों में, जहां कई को संभालने के लिए आवश्यक हो सकता है के लिए सीमित है मूल्यों को एक साथ सहेजने की आवश्यकता है, जैसे नेस्टेड फ़ंक्शन कॉल, लूप या अन्य थ्रेड में।तो, DRY सिद्धांत के अनुसार, बल्कि हर एक लिखने की तुलना में, एक कारखाने समारोह में मदद कर सकते हैं:

def Cache(): 
    def cache(value): 
     cache.value = value 
     return value 
    return cache 

cache1 = Cache() 
for s in strings: 
    if cache1(regex.match(s)): 
     # use another at same time 
     cache2 = Cache() 
     if cache2(somethingelse) != cache1.value: 
      process(cache2.value) 
     print cache1.value.groups() 
      ... 
+0

का मेरा पसंदीदा हिस्सा है इसके बारे में हैकी क्या है? कार्यों को गुण मिलता है। उन्हें इस्तेमाल करें। – aaronasterling

+0

इसके बारे में केवल एक समय में एक पकड़ रहा है: नहीं। 'डीफ कैश (** kwargs): kwargs में कुंजी के लिए: setattr (कैश, कुंजी, kwargs [कुंजी]) ' – aaronasterling

+0

@AaronMcSmooth। दिलचस्प विचार - यह सुनिश्चित नहीं है कि एकाधिक धागे को संभालने के लिए इसका उपयोग कैसे किया जाए, क्योंकि प्रत्येक को एक अद्वितीय कुंजी का उपयोग करने की आवश्यकता होगी। – martineau

1

जब भी मुझे लगता है कि मेरी पाश तर्क हो रही है जटिल है कि मैं क्या मैं तर्क के किसी भी अन्य बिट के साथ होता है: मैं इसे एक समारोह में निकालने के लिए। पाइथन में यह कुछ अन्य भाषाओं की तुलना में यह साफ करना बहुत आसान है।

def matching(strings, regex): 
    for s in strings: 
     r = regex.match(s) 
     if r: yield r 

और फिर जब आप इसे उपयोग करना चाहते हैं, पाश ही के रूप में सरल है के रूप में वे मिल:

for r in matching(strings, regex): 
    print r.groups() 
+0

सामान्य रूप से अच्छी प्रोग्रामिंग तकनीक, खासकर उस मामले में जहां फ़ंक्शन एकाधिक मान देता है। हालांकि मुझे लगता है कि जब आप बस इतना करना चाहते हैं तो एक ही मूल्य असाइन करें और परीक्षण करें। – martineau

+0

हर किसी के पास यहां एक अलग व्यक्तिगत सीमा होगी। दिया गया विशेष उदाहरण शायद सीमा रेखा है: लूप निकालने से यह थोड़ा क्लीनर बन जाता है, लेकिन इसे छोड़कर वास्तव में वह सब बुरा नहीं होता है। यदि आपको नहीं लगता कि मूल कोड गन्दा दिखता है तो इसे छोड़ दें। मैं बस यह इंगित कर रहा हूं कि सामान्य मामले में मैं लूप्स से संपर्क करता हूं जो गन्दा दिखता है। – Duncan

0

फिर भी

तो कोड है कि बस ब्याज की वस्तुओं उत्पन्न निकालने एक और जवाब "असाइन एंड टेस्ट" रेसिपी का उपयोग करना है, O'Reilly Media के जुलाई 2002 में पायथन कुकबुक और online के सक्रिय संस्करण पर प्रकाशित एक कथन में असाइन करने और परीक्षण करने की अनुमति देने के लिए "असाइन करें और परीक्षण करें" नुस्खा का उपयोग करना है। यह वस्तु उन्मुख है, जो की जड़ यह है:

# from http://code.activestate.com/recipes/66061 
class DataHolder: 
    def __init__(self, value=None): 
     self.value = value 
    def set(self, value): 
     self.value = value 
     return value 
    def get(self): 
     return self.value 

यह वैकल्पिक रूप से कस्टम __call__() विधि नीचे दिखाया गया जोड़ने उदाहरणों 'मूल्यों को पुनः प्राप्त करने का एक वैकल्पिक तरीका प्रदान करने के लिए थोड़ा संशोधित किया जा सकता है - जो है, जबकि कम स्पष्ट , मुझे लगता है कि 'DataHolder' ऑब्जेक्ट के लिए पूरी तरह तार्किक चीज़ की तरह लगता है, मुझे लगता है।

def __call__(self): 
     return self.value 

अपने उदाहरण फिर से लिखा अनुमति देने के लिए किया जा:

r = DataHolder() 
for s in strings: 
    if r.set(regex.match(s)) 
     print r.get().groups() 
# or 
     print r().groups() 

के रूप में भी मूल नुस्खा में बताया गया है, यदि आप इसे एक बहुत का उपयोग करें, वर्ग और/या करने के लिए इसे का एक उदाहरण जोड़ने __builtin__ मॉड्यूल यह दुनिया में उपलब्ध कराना संभावित कमियां के बावजूद बहुत आकर्षक है:

import __builtin__ 
__builtin__.DataHolder = DataHolder 
__builtin__.data = DataHolder() 

मैं इस सवाल का मेरे अन्य जवाब में उल्लेख किया है, यह ध्यान दिया जाना चाहिए कि इस दृष्टिकोण की सीमा है एक समय में केवल एक परिणाम/मूल्य धारण करने के लिए एड, ऐसे परिस्थितियों को संभालने के लिए एक से अधिक उदाहरणों की आवश्यकता होती है जहां कई मानों को एक साथ सहेजने की आवश्यकता होती है, जैसे नेस्टेड फ़ंक्शन कॉल, लूप या अन्य थ्रेड। इसका मतलब यह नहीं है कि आपको इसका इस्तेमाल करना चाहिए या अन्य जवाब, बस इतना प्रयास करना आवश्यक होगा।

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