web-dev-qa-db-ja.com

キーワード引数を指定したmap()関数の使用

これは、map関数を使用しようとしているループです。

volume_ids = [1,2,3,4,5]
ip = '172.12.13.122'
for volume_id in volume_ids:
    my_function(volume_id, ip=ip)

これを行う方法はありますか? ipパラメータがない場合は簡単ですが、それを処理する方法がわかりません。

34
Cameron Sparr

functools.partial() を使用:

_from functools import partial

mapfunc = partial(my_function, ip=ip)
map(mapfunc, volume_ids)
_

partial()は、新しいcallableを作成します。これにより、新しいcallableに渡されるものに加えて、引数(キーワード引数を含む)がラップされた関数に適用されます。

71
Martijn Pieters

ここにラムダアプローチがあります(良くない、違うだけです)

volume_ids = [1,2,3,4,5]
ip = '172.12.13.122'
map(lambda ids: my_function(ids, ip), volume_ids);
12
Jason Sperske

これはリスト内包で簡単に行うことができます。

volume_ids = [1,2,3,4,5]
ip = '172.12.13.122'
results = [my_function(i,ip=ip) for i in volume_ids]
6
shapr

一般に、mapを使用して関数にキーワードを渡すには、その関数をディクショナリーをアンパックするものでラップし、マップするディクショナリーのイテラブルを渡します。例:

from itertools import product

volume_ids = [1,2,3,4,5]
volume_ids = (("volume_id", volume_id) for volume_id in volume_ids)
ips = [("ip", '172.12.13.122')]
kwargs_iterable = map(dict, product(volume_ids, ips))

result = map(lambda kwargs: my_function(**kwargs), kwargs_iterable)

ただし、特殊なケースの場合、より簡単な解決策は次のとおりです。

map(my_function, volume_ids, [ip]*len(volume_ids))

これは簡潔で、インポートに依存しません。もう1つの可能性は、itertoolsの製品とスターマップを組み合わせることです。

from itertools import product, starmap

ips = [ip]
starmap(my_function, product(volume_ids, ips))

これは、1つ以上のIPアドレス、または2つ以上の変数を持つ設定にうまく一般化します。

1
Jonas Dahlbæk

これはどう?

results = []
for volume_id in volume_ids:
    results.append(my_function(volume_id, ip=ip))

これは、1行ではなく3行のコードです。モジュールなどから特別なケースのヘルパーをインポートする代わりに、3行の明確で明白なコードです。この議論はおそらく好みの問題ですが、話し相手によってはかなりの重みがあります。

0
Armin Rigo