2017-09-21 9 views
2

先物を使ったタプルアンパックのようなものを実現するための寛大な/慣用的な方法は何ですか?python先物とタプルのアンパック

私は

a, b, c = f(x) 
y = g(a, b) 
z = h(y, c) 

のようなコードがあると私は先物を使用するように変換したいと思います。 理想的には私が

a, b, c = ex.submit(f, x) 
y = ex.submit(g, a, b) 
z = ex.submit(h, y, c) 

のようなものを書きたいというの最初の行は、しかし

TypeError: 'Future' object is not iterable 

をスローします。 を3回追加することなくa,b,cを取得するにはどうすればよいですか?すなわち、私はこれのように記述することを避けるためにたいと思います。たとえば、あなたならば最初:、

import operator as op 
fut = ex.submit(f, x) 
a = client.submit(op.getitem, fut, 0) 
b = client.submit(op.getitem, fut, i) 
c = client.submit(op.getitem, fut, 2) 
y = ex.submit(g, a, b) 
z = ex.submit(h, y, c) 

私は潜在的な解決策は、以下のようなunpack関数を記述することであると思い働く

import operator as op 
def unpack(fut, n): 
    return [client.submit(op.getitem, fut, i) for i in range(n)] 

a, b, c = unpack(ex.submit(f, x), 3) 
y = ex.submit(g, a, b) 
z = ex.submit(h, y, c) 

定義:

def f(x): 
    return range(x, x+3) 
x = 5 
g = op.add 
h = op.mul 

を、あなたが

を取得
z.result() #===> 77 

私はこれがすでに存在するかもしれないと考えました。


上記は、dask.distributed.Futureでのみ動作します。プレーンでは動作しませんconcurrent.futures.Future

+1

する "エラーをスローします。"何がエラーですか? –

+0

@JohnZwinck 'TypeError: '未来'のオブジェクトは反復可能ではない' –

+0

'operator.itemgetter'は複数の項目を取得できます。しかし、そのコードを見てください。これは反復を行うクラスです。 – hpaulj

答えて

2

一目:

https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Future

あなたはFutureオブジェクトではなく、f(x)を実行した結果を返しますsubmit

afuture = ex.submit(f, x) 
a,b,c = afuture.result() 
... 

ような何かをする必要がありますことを示唆しています。

このSO答えが先物を連鎖することは些細なことではないことを示しています

How to chain futures in a non-blocking manner? That is, how to use one future as an input in another future without blocking?

+0

「未来」。result() 'コールは' f'への呼び出しをブロックします。これは先物を使用する目的を無効にします。 –

+0

@DanielMahler、アンパックすることなく連鎖の例を教えてくれますか?あなたは '未来 'でいくつかの基本的なことをしたように聞こえます。私たちを教えてください。これらの3つの追加通話は何ですか? – hpaulj