i-focus i-focus BB
    • カテゴリ
    • 最近
    • タグ
    • 人気
    • ユーザー
    • グループ
    • 登録
    • ログイン

    lambdaの内包表記で躓いた話

    Python
    python
    1
    1
    225
    もっと見る
    • 古いものから新しい順
    • 新しいものから古い順
    • 最高評価
    返信
    • スレッドとして返信する
    投稿するのにログインして下さい
    このスレッドが削除されました。スレッド管理権を持っているユーザーにしか読めません。
    • i_yamasakiI
      i_yamasaki
      最後に編集した時間i_yamasaki

      結論:
      lambda式の参照は呼び出されたタイミングで決まる

      本題:
      またミュータブル、イミュータブル関連で躓いたのでメモ
      リスト内辞書にラムダ式を持たせて比較を行おうとした。

      l = ["a", "b", "c", "d", "e"]
      
      funcL = [
          {
              "str": s,
              "func": lambda x: x == s
          } for s in l
      ]
      
      checkStr = "a"
      
      for func in funcL:
          print(checkStr, func["str"], func["func"](checkStr))
      
      # >> std out
      # >> a a False
      # >> a b False
      # >> a c False
      # >> a d False
      # >> a e False
      

      なんでaとaがFalseになってるの!?となったところで確認してみるとfunc["func"]で比較しているsがすべてeになっている。

      l = ["a", "b", "c", "d", "e"]
      
      funcL = [
          {
              "str": s,
              "func": lambda _x: print(s)
          } for s in l
      ]
      
      for func in funcL:
          func["func"](None)
      
      # >> std out
      # >> e
      # >> e
      # >> e
      # >> e
      # >> e
      

      いろいろ試したところラムダ式の中身が確定されるのはラムダ式が呼び出されたタイミングで参照されている値であり、今回の例ではそれぞれのラムダ式が呼び出された時点でのsの参照先が"e"のためすべてのラムダ式で"e"と比較されていたらしい。

      解決策:
      おとなしくラムダ式を使わずに比較する。

      l = ["a", "b", "c", "d", "e"]
      
      checkStr = "a"
      
      for s in l:
          print(checkStr, s, checkStr == s)
      
      # >> std out
      # >> a a True
      # >> a b False
      # >> a c False
      # >> a d False
      # >> a e False
      
      1 件の返信 最後の返信 返信 引用 0
      • First post
        Last post