73134


辞書内包表記で記載すると可読性が高いと思い、その方法を探しています。  
代案としては下記に記載した通り、関数でTupleを返しdict()を使用する事で実現ができております。

正直、「辞書の内包表記はPythonの構文で定義されているため、関数で返すという事はできない。」という結論になるのではないかと思っております。  
もしそうであれば、その旨回答して頂けると助かります  
※ドキュメントなどは見つからなかったので提示して頂けると更に嬉しいです  
※代案についても他にやり方があれば是非教えてください

詳細は下記に記載します

## やりたい事

このようなforで書いたコードを

[code]

    l = ['a', 'b']
    def f(s):
      # 実際にはそれなりにコストがかかる処理でKeyとValueを作成する
      k = s * 2
      v = s * 3
      return k, v
    d = {}
    for s in l:
      k, v = f(s)
      d[k] = v
    print(d) # {'aa': 'aaa', 'bb': 'bbb'}
    
[/code]

以下のようなイメージで内包表記で書きたい

[code]

    l = ['a', 'b']
    def f(s):
      # 実際にはそれなりにコストがかかる処理でKeyとValueを作成する
      k = s * 2
      v = s * 3
      # ※ここでどのように返せばよいかを知りたい
      return k:v # イメージです。（構文エラーになります）
    
    d = {f(s) for s in l}
    print(d) # {'aa': 'aaa', 'bb': 'bbb'}
    
[/code]

※Keyの重複に対する考慮は不要です。

## 代案

一旦リスト内包表記でList[Tuple]とした上で、dictに変換する

[code]

    l = ['a', 'b']
    def f(s):
      # 実際にはそれなりにコストがかかる処理でKeyとValueを作成する
      k = s * 2
      v = s * 3
      return k, v
    
    d = dict([f(s) for s in l])
    print(d) # {'aa': 'aaa', 'bb': 'bbb'}
    
[/code]


CC BY-SA 4.0
2021-01-07T05:17:09.500
73132
2021-01-12T01:21:59.313
2021-01-12T01:21:59.313
13022
13022
question
python python3
辞書内包表記で返す値を関数から取得したい


`f(s)` の戻り値をタプルにした上でジェネレーター式にすれば高速に書けそうです。

[code]

    d = dict(f(s) for s in l)
    
[/code]

これならリストへの変換もはさみません。

追記：  
今こんな感じで比較してみたんですけどあんまり差ないですね……。

[code]

    >>> def f(x, n):
    ...   y = [x for x in 'xyzw' * 100]
    ...   return (x+str(n), x+random.choice(y))
    ... 
    >>> timeit.timeit('x = dict([f(x, n) for n, x in enumerate(\'abcdef\'*10000)])', globals=locals(),number=100)
    41.55919947102666
    >>> timeit.timeit('x = dict(f(x, n) for n, x in enumerate(\'abcdef\'*10000))', globals=locals(),number=100)
    40.46618250303436
    >>> 
    
[/code]

リスト内包が最適化されてるのと、`dict` が組み込み関数なので処理が特別なのかもしれません。なのであんま気にしなくてよいのかも。


CC BY-SA 4.0
2021-01-07T05:47:23.450
73134
2021-01-07T06:21:00.137
2021-01-07T06:21:00.137
39645
39645
73132
answer


`f()` 関数の戻り値を dict 型のインスタンスにして
[functools.reduce](https://docs.python.org/3.8/library/functools.html#functools.reduce)
を使います。

[code]

    from functools import reduce
    
    def f(s):
      k = s * 2
      v = s * 3
      return {k: v}
    
    l = ['a', 'b']
    d = reduce(lambda d1, d2: (d1.update(d2) or d1), map(f, l), {})
    print(d)
    =>
    {'aa': 'aaa', 'bb': 'bbb'}
    
[/code]


CC BY-SA 4.0
2021-01-07T07:45:10.583
73138
2021-01-07T07:45:10.583
73132
answer