5

私は、より短く、よりPythonで、読みやすいPythonを作成しようとしています。そして、私はプロジェクトオイラーの問題8(1000桁の数字で5つの連続した数字の最大の積を見つける)のためのこの実用的な解決策を持っています。

このスクリプトのよりPython的なバージョンを作成するための提案はありますか?

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()

助言がありますか?みんなありがとう!

4

5 に答える 5

4

私は完全な答えに取り組んでいますが、今のところここにワンライナーがあります

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

編集:どうぞ!検索用の1つのライナー。リスト内包表記は素晴らしいです。

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))
于 2012-07-27T18:04:12.850 に答える
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))))
于 2012-07-27T18:06:53.253 に答える
1

これが私の解決策です。私は自分が書く方法を知っている最も「Pythonic」なコードを書こうとしました。

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)

間違いなく、これは使用するのに理想的なケースの1つな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で、すべてのI/Oにそれを使用するのが私の習慣です。この小さな問題の場合は、ワンライナーを実行するだけで済みます。PyPyなどを使用している場合は、小さなプログラムの実行が終了して終了すると、ファイルが閉じられます。しかし、私は2ライナーを使用するのが好きなwithので、それを書きました。

@StevenRumbalskiのワンライナーが大好きです。

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です。

于 2012-07-27T19:04:15.760 に答える
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))

Python 3.xを使用している場合は、に置き換える必要がありreduceますfunctools.reduce

于 2012-07-27T18:02:51.730 に答える
0

その最後のビットが何であったかを説明する限り、最初に:stringと呼ばれる空を作成します。numstring

numstring = ''

次に、ファイル内のテキストのすべての行(またはstringsの行)をループします。txt8.txt

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
于 2012-07-27T18:02:30.357 に答える