

以下に示す、戻り値に関する記述の意味が分かりません。

[code]

    return {k: v for k, v in balance.items()
            if isinstance(v, str) and float(v)}
    
[/code]

リスト内包表記を参考に、自分なりに、以下の記述と同等表現と考えたのですが合ってますか。

[code]

    return{}
    for k, v in balance.item():
        if (isinstance(v, str) and float(v)):
           .setdefault(k, v) 
    
[/code]

コードの全体像は下記のとおりです。

[code]

    def balance(self):
        endpoint = self.url + '/api/accounts/balance'
        return self._request(endpoint=endpoint)
    
    @property
        def position(self):
        balance = self.balance()
        return {k: v for k, v in balance.items()
                if isinstance(v, str) and float(v)}
    
[/code]

※上記コードは [#12 Python×ビットコイン自動売買 | クラスを作成してコードを読みやすくしよう！](https://tech-
diary.net/create-coincheck-class-object/) で紹介されているコードです。


CC BY-SA 4.0
2021-10-09T16:31:00.920
82980
2022-11-11T10:06:00.433
2021-10-09T17:47:10.890
47127
48018
question
python
辞書型の戻り値の記述について


> リスト内包表記を参考に、自分なりに、以下の記述と同等表現と考えたのですが合ってますか。

実際に実行してみると判りますが、`.setdefault(k, v)` の部分で syntax error になります。syntax error
を修正したとしても、最初に `return{}` としてしまっているので `Coincheck.position` property は常に empty
dict(空(カラ)の辞書)を返す事になります。

以下は動作チェック用の stub code になります。

[code]

    if __name__ == '__main__':
      import json
      from pprint import pprint
    
      cc = Coincheck('a', 'b')
    
      # 取引所APIドキュメント|仮想通貨取引所のCoincheck(コインチェック)
      # https://coincheck.com/ja/documents/exchange/api#account-balance
      cc.balance = lambda: json.loads('''
        {
          "success": true,
          "jpy": "0.8401",
          "btc": "7.75052654",
          "jpy_reserved": "3000.0",
          "btc_reserved": "3.5002",
          "jpy_lend_in_use": "0",
          "btc_lend_in_use": "0.3",
          "jpy_lent": "0",
          "btc_lent": "1.2",
          "jpy_debt": "0",
          "btc_debt": "0"
        }''')
    
      print('Original:')  
      pprint(cc.position)
    
      # replace Coincheck.position property
      def myposition(self):
        balance = self.balance()
        dic = {}
        for k, v in balance.items():
          if isinstance(v, str):
            try:
              if float(v): dic[k] = v
            except ValueError:
              continue
    
        return dic
      
      Coincheck.position = property(myposition)
    
      print('Replaced:')  
      pprint(cc.position)
    
    # 実行結果
    Original:
    {'btc': '7.75052654',
     'btc_lend_in_use': '0.3',
     'btc_lent': '1.2',
     'btc_reserved': '3.5002',
     'jpy': '0.8401',
     'jpy_reserved': '3000.0'}
    
    Replaced:
    {'btc': '7.75052654',
     'btc_lend_in_use': '0.3',
     'btc_lent': '1.2',
     'btc_reserved': '3.5002',
     'jpy': '0.8401',
     'jpy_reserved': '3000.0'}
    
[/code]

例外処理を行っているのは、`float()` は `ValueError` を発生させる場合があるからです。例えば、

[code]

      cc.balance = lambda: {
        'a': '1.0', 'b': '2.0', 'c': '3.0c', 'd': 4.0
      }
    
[/code]

として元のコードを実行すると、以下の様にエラーが発生します。

[code]

    Traceback (most recent call last):
      File "coin_check.py", line 74, in <module>
        print(f'Original: {cc.position}')
      File "coin_check.py", line 61, in position
        return {k: v for k, v in balance.items()
      File "coin_check.py", line 62, in <dictcomp>
        if isinstance(v, str) and float(v)}
    ValueError: could not convert string to float: '3.0c'
    
[/code]

※ API ドキュメントを読む限り `ValueError` が発生する事はなさそうなので上記の例外処理は不要かもしれません。


CC BY-SA 4.0
2021-10-09T18:28:09.177
82981
2021-10-10T02:19:39.500
2021-10-10T02:19:39.500
47127
47127
82980
answer


`return`の後の式はリスト内包表記では無く、[5.5. 辞書型
(dictionary)](https://docs.python.org/ja/3/tutorial/datastructures.html#dictionaries)で述べられている「辞書内包表現」という物です。

> さらに、辞書内包表現を使って、任意のキーと値のペアから辞書を作れます:
[code]

>     >>> {x: x**2 for x in (2, 4, 6)}
>     {2: 4, 4: 16, 6: 36}
>  
[/code]

他にも「集合内包表記」と言う物もあります。これらはリスト内包表記の親戚みたいな物で、リストの代わりに辞書(dict)または集合(set)を作る事になります。

内包表記を使わずに、かつ、ifもforの外側に展開した場合は、次のようになります。

[code]

    data = {}
    for k, v in balance.items():
        if isinstance(v, str) and float(v):
            data[k] = v
    return data
    
[/code]


CC BY-SA 4.0
2021-10-10T04:44:28.870
82983
2021-10-10T04:49:56.507
2021-10-10T04:49:56.507
7347
7347
82980
answer