2012-07-27 15 views
5

लिखना मैं छोटा, अधिक पायथनिक, पठनीय पायथन का उत्पादन करने की कोशिश कर रहा हूं। और मेरे पास Project Euler's problem 8 (1000 अंकों की संख्या में 5 अनुक्रमिक अंकों का सबसे बड़ा उत्पाद ढूंढने के लिए) का यह समाधान समाधान है।छोटे, पठनीय, पायथनिक कोड

इस स्क्रिप्ट का एक और पायथन संस्करण लिखने के लिए सुझाव?

numstring = '' 
for line in open('8.txt'): 
    numstring += line.rstrip() 

nums = [int(x) for x in numstring] 

best=0 
for i in range(len(nums)-4): 
    subset = nums[i:i+5] 
    product=1 
    for x in subset: 
     product *= x 
    if product>best: 
     best=product 
     bestsubset=subset 

print best 
print bestsubset 

उदाहरण के लिए: नीचे स्निपेट के लिए एक-लाइनर होना चाहिए। मुझे यकीन है कि यहां एक पिछला विषय है लेकिन मुझे यकीन नहीं है कि मैं नीचे क्या कर रहा हूं इसका वर्णन कैसे करें।

numstring = '' 
for line in open('8.txt'): 
    numstring += line.rstrip() 

कोई सुझाव? धन्यवाद दोस्तों!

उत्तर

1

यहाँ मेरी समाधान है। मैंने सबसे अधिक "पायथनिक" कोड लिखने की कोशिश की जो मुझे पता है कि कैसे लिखना है।

with open('8.txt') as f: 
    numstring = f.read().replace('\n', '') 

nums = [int(x) for x in numstring] 

def sub_lists(lst, length): 
    for i in range(len(lst) - (length - 1)): 
     yield lst[i:i+length] 

def prod(lst): 
    p = 1 
    for x in lst: 
     p *= x 
    return p 

best = max(prod(lst) for lst in sub_lists(nums, 5)) 
print(best) 

बेशक, इस आदर्श मामलों में से एक reduce उपयोग करने के लिए है, इसलिए हो सकता है prod() होना चाहिए:

# from functools import reduce # uncomment this line for Python 3.x 
from operator import mul 
def prod(lst): 
    return reduce(mul, lst, 1) 

मैं कहाँ करने के लिए एक कारण नहीं है एक-लाइनर्स लिखने की कोशिश करने के लिए पसंद नहीं है एक से अधिक लाइन है। मुझे वास्तव में with कथन पसंद है, और यह सभी आदतों के लिए उपयोग करने की मेरी आदत है। इस छोटी सी समस्या के लिए, आप केवल एक-लाइनर कर सकते हैं, और यदि आप पीपीपीई का उपयोग कर रहे हैं या कुछ तो फ़ाइल बंद हो जाएगी जब आपका छोटा प्रोग्राम निष्पादित हो जाता है और बाहर निकलता है। लेकिन मुझे with का उपयोग करके दो-लाइनर पसंद है इसलिए मैंने इसे लिखा।

मैं @Steven Rumbalski द्वारा एक लाइनर प्यार:

nums = [int(c) for c in open('8.txt').read() if c.isdigit()] 

यहाँ कैसे मैं शायद कि लिखते थे बताया गया है:

with open("8.txt") as f: 
    nums = [int(ch) for ch in f.read() if ch.isdigit()] 

फिर, लघु कार्यक्रम के इस प्रकार के लिए, अपनी फ़ाइल हो जाएगा जब प्रोग्राम निकलता है तो बंद हो जाता है ताकि फ़ाइल को बंद होने के बारे में आपको चिंता करने की ज़रूरत न हो; लेकिन मुझे with का उपयोग करने की आदत बनाना पसंद है।

+0

हाँ मुझे लगता है कि 'sub_lists (lst, लंबाई) 'की परिभाषा बहुत समझ में आता है। यह जादू संख्या का उपयोग 'लेन (अंक) -4' के रूप में करने में भ्रमित था। – dyln

+0

भी 'उपज' वाक्यविन्यास – dyln

+0

जानने के लिए अच्छा है प्रोड की परिभाषा का उपयोग करना 'ऑपरेटर' से बिल्टिन 'mul' का उपयोग करने से काफी धीमा है। –

0

जहाँ तक बताने के लिए क्या है कि पिछले सा था, पहली आपके द्वारा बनाए गए एक खाली string बुलाया numstring:

numstring = '' 
फिर

आप पाश txt फ़ाइल 8.txt में पाठ (या string रों की लाइन) के हर लाइन पर :

for line in open('8.txt'): 

और इसलिए आप पाते हैं कि हर लाइन के लिए, आप इसे करने line.rstrip() का परिणाम जोड़ना चाहते हैं। rstrip 'स्ट्रिप्स' खाली स्थान के स्ट्रिंग से (नई-पंक्तियों, रिक्त स्थान आदि):

numstring += line.rstrip() 

कहो आप किसी फ़ाइल, 8.txt कि पाठ शामिल था: LineOne \nLyneDeux\t\nLionTree आप एक परिणाम है कि अंत में कुछ इस तरह देखा मिलता था :

>>>'LineOne' #loop first time 
>>>'LineOneLyneDeux' # second time around the bush 
>>>'LineOneLyneDeuxLionTree' #final answer, reggie 
+0

विचारशील स्पष्टीकरण @TankorSmash के लिए धन्यवाद। मुझे अपने प्रश्न में स्पष्ट होना चाहिए था, मेरा मतलब क्या था: मैं नहीं जानता कि मैं यहां क्या कर रहा हूं इसका वर्णन करने के लिए संक्षेप में पर्याप्त विषयों की खोज करने के लिए पर्याप्त है। – dyln

+1

आह। यह सब अच्छा है। – TankorSmash

0

यहां एक पूर्ण समाधान है!

with open("8.txt") as infile: 
    number = infile.replace("\n", "") 

तो लगातार 5 नंबर के साथ सूची की एक सूची बना:

cons_numbers = [list(map(int, number[i:i+5])) for i in range(len(number) - 4)] 

तो सबसे बड़ा खोजने के लिए और इसे प्रिंट:

print(max(reduce(operator.mul, nums) for nums in cons_numbers)) 

यदि आप पहले नंबर पढ़ा पायथन 3.x का उपयोग करके आपको को functools.reduce के साथ प्रतिस्थापित करने की आवश्यकता है।

+0

आप ''' \ n '' ''' – JBernardo

+0

@JBernardo के साथ बस '' \ n'' को प्रतिस्थापित कर सकते हैं: निश्चित रूप से, लेकिन यह __any__ व्हाइटस्पेस पर विभाजित होगा, और \ "" \ n "" इरादा को और स्पष्ट कर देगा। – orlp

+0

मैं 'ओपन (...) के बारे में बात कर रहा था। पढ़ें()। बदलें (' \ n ',' ')' – JBernardo

4

मैं एक पूरा जवाब पर अब यहाँ काम कर रहा हूँ, लेकिन के लिए एक लाइनर है

numstring = ''.join(x.rstrip() for x in open('8.txt')) 

संपादित करें: ये रहा! खोज के लिए एक लाइनर। सूची समझ अद्भुत हैं।

from operator import mul 
def prod(list): 
    return reduce(mul, list) 

numstring = ''.join(x.rstrip() for x in open('8.txt')) 
nums = [int(x) for x in numstring] 
print max(prod(nums[i:i+5]) for i in range(len(nums)-4)) 
+0

यह वास्तव में चालाक है। आप मूल के बजाय लैम्ब्डा का उपयोग करने के बारे में क्या सोचते हैं? i.e. 'def prod (सूची): वापसी कम करें (लैम्ब्डा एक्स, वाई: एक्स * वाई, सूची)' – dyln

+0

यह भी अच्छी तरह से काम करता है। मुझे नहीं पता कि पाइथन ने इसे क्यों नहीं बनाया - यह एक बहुत ही सामान्य आवश्यकता है (परियोजना यूलर के लिए और भी बहुत कुछ!), और यह वास्तव में आर –

+1

में अंतर्निहित होने में मदद करता है जहां पाइथन एक निर्मित- 'operator.mul' की तरह, आमतौर पर 'लैम्ब्डा' के बजाय इसका उपयोग करने के लिए अधिक कुशल होता है।इस तरह के कुछ के लिए, दक्षता वास्तव में कोई फर्क नहीं पड़ता; आपके कंप्यूटर को आंखों के झपकी में जवाब मिलेगा, ताकि आप जो भी पसंद करते हैं उसका उपयोग कर सकें। लेकिन सामान्य रूप से, 'ऑपरेटर' से आयात करने की आदत में होना बुरा नहीं है जब आप 'कम() 'या' map() 'या जो कुछ भी कर रहे हैं। – steveha

4
from operator import mul 

def product(nums): 
    return reduce(mul, nums) 

nums = [int(c) for c in open('8.txt').read() if c.isdigit()] 
result = max((product(nums[i:i+5]) for i in range(len(nums)))) 
+0

मैं डाउनवॉट्स के साथ शांत हूं, लेकिन कृपया मुझे बताएं क्यों। –

+0

मैंने डाउनवोट नहीं किया, लेकिन ओपी ने 'रेंज (लेंस (अंक) - 4) ' – thebjorn

+0

@thebjorn: मैंने जानबूझकर 4 घटाया नहीं क्योंकि यह परिणाम को प्रभावित नहीं करता था। अगर मैं घटाना चाहता था तो शायद मैंने 'रेंज (लेंस (अंक) - 5 + 1) जैसे कुछ किया होगा और शायद उस बिंदु पर जादू संख्या भी नामित किया होगा। –

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