0

私は、ユーザーが長方形の量、開始、および停止を指定する関数の積分を見つけるためのプログラムに取り組んでいました。

注:長方形の左端の点を使用しています。

私は機能が完璧に機能しています(少なくとも、完璧に見えます)。しかし、私はそれのためにワンライナーを書くことができるかどうかを見たかったのですが、私が使用しているのでどのようにすればいいのかわかりませんeval()。これが私の元のコードです:

def integral(function, n=1000, start=0, stop=100):
    """Returns integral of function from start to stop with 'n' rectangles"""
    increment, rectangles, x = float((stop - start)) / n, [], start
    while x <= stop:
        num = eval(function)
        rectangles.append(num)
        if x >= stop: break
        x += increment
    return increment * sum(rectangles)

これは正常に機能します。

>>> integral('x**2')
333833.4999999991

実際の答えは1000000/3ですので、私の関数はかなり良い見積もりを出します(1000個の長方形のみ)。

ワンライナーでの私の試み:

def integral2(function, n=1000, start=0, stop=100): rectangles = [(float(x) / n) for x in range(start*n, (stop*n)+1)]; return (float((stop-start))/n) * sum([eval(function) for x in rectangles])

ただし、セミコロンを使用しているため、これは真のワンライナーではありません。また、それは少し遅く(数秒長くかかります、これはかなり重要です)、間違った答えを与えます:

>>> integral2('x**2')
33333833.334999967

それで、この関数にワンライナーソリューションを使用することは可能ですか?eval()実装方法とfloat(x)/n同じリスト内包表記がわかりませんでした。float(x)/n関数内で仮想の「ステップ」を実現しrangeます。

ありがとう!

4

3 に答える 3

2
def integral2(function, n=1000, start=0, stop=100): return (float(1)/n) * sum([eval(function) for x in [(float(x) / n) for x in range(start*n, (stop*n)+1)]])

integralintegral2:の間には大きな違いがあることに注意してください。長方形をintegral2作成しますが(stop*n)+1-(start*n)、長方形integralのみを作成しnます。


In [64]: integral('x**2')
Out[64]: 333833.4999999991
In [68]: integral2('x**2')
Out[68]: 333338.33334999956

In [69]: %timeit integral2('x**2')
1 loops, best of 3: 704 ms per loop

In [70]: %timeit integral('x**2')
100 loops, best of 3: 7.32 ms per loop

おそらく、より比較可能な翻訳は次のintegralようになります。

def integral3(function, n=1000, start=0, stop=100): return (float(stop-start)/n) * sum([eval(function) for x in [start+(i*float(stop-start)/n) for i in range(n)]])

In [77]: %timeit integral3('x**2')
100 loops, best of 3: 7.1 ms per loop

もちろん、これを(ひねくれた?)娯楽以外のワンライナーにする目的はないということは言うまでもありません:)

于 2013-02-08T03:06:55.657 に答える
2

Python 自体としてeval受け取る場合は使用する必要はありません関数を使用して float 値のリストを生成することもできますfunctioncallablenumpy.arange

ケース 1:functionは Python ですcallable

def integrate(f, n, start, end):
    return sum([f(i)*(abs(start-end)/float(n)) for i in np.arange(start, end, abs(start-end)/float(n))])

ケース 2: functionPython ではないcallable

def integrate(f, n, start, end):
    return sum([eval(f)*(abs(start-end)/float(n)) for x in np.arange(start, end, abs(start-end)/float(n))])
于 2013-02-08T03:13:29.643 に答える
0

numpy の linspace を使って不正行為をしてみませんか?

integrate = lambda F, n0, nf: sum([F(x)*(abs(nf-n0)/(abs(nf-n0)*300))for x in np.linspace(n0, nf, abs(nf-n0)*300)])

関数 F、下限 n0、上限 nf を取ります。x**2 が 0 から 5 の間でどのように機能するかを次に示します。

In [31]: integrate(lambda x: x**2, 0, 5)
Out[31]: 41.68056482099179

かなり近いです。

編集:これが私のlinspaceワンライナーです。

linspace = lambda lo, hi, step:[lo + (hi-lo)/step*i + (hi-lo)/(step*step-1)*i for i in range(step)]

それを完全なワンライナーインテグレーターにくすぐる方法があります。それはあなたに任せます。

于 2016-08-13T07:38:44.360 に答える