How to create a dictionary containing lambda expressions using comprehension list? [duplicate]











up vote
2
down vote

favorite













This question already has an answer here:




  • How do I create a list of Python lambdas (in a list comprehension/for loop)?

    8 answers




I am trying to generate (something like) the following dictionary:



funcs1 = {
'0':lambda x:x==0,
'1':lambda x:x==1,
'2':lambda x:x==2,
'3':lambda x:x==3,
'4':lambda x:x==4,
'5':lambda x:x==5,
}


I tried to create the dictionary with a list comprehension like this:



funcs2 = {str(i):lambda x:x==i for i in range(0,6)}


Or simply using a for loop:



funcs3 = {}
for i in range(0,6):
funcs3.update({str(i): lambda x:x==i})


However, funcs2 and funcs3 are not the same as funcs1, for example, when calling the element '0' of each one of them and applying it to 0, the results are different:



funcs1['0'](0)
Out[2]: True

funcs2['0'](0)
Out[3]: False

funcs3['0'](0)
Out[4]: False


Can somebody please help me out and point out where I am making a mistake?










share|improve this question













marked as duplicate by MisterMiyagi, chepner python
Users with the  python badge can single-handedly close python questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 19 at 21:04


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.















  • docs.python-guide.org/writing/gotchas/#late-binding-closures
    – ritlew
    Nov 19 at 20:59















up vote
2
down vote

favorite













This question already has an answer here:




  • How do I create a list of Python lambdas (in a list comprehension/for loop)?

    8 answers




I am trying to generate (something like) the following dictionary:



funcs1 = {
'0':lambda x:x==0,
'1':lambda x:x==1,
'2':lambda x:x==2,
'3':lambda x:x==3,
'4':lambda x:x==4,
'5':lambda x:x==5,
}


I tried to create the dictionary with a list comprehension like this:



funcs2 = {str(i):lambda x:x==i for i in range(0,6)}


Or simply using a for loop:



funcs3 = {}
for i in range(0,6):
funcs3.update({str(i): lambda x:x==i})


However, funcs2 and funcs3 are not the same as funcs1, for example, when calling the element '0' of each one of them and applying it to 0, the results are different:



funcs1['0'](0)
Out[2]: True

funcs2['0'](0)
Out[3]: False

funcs3['0'](0)
Out[4]: False


Can somebody please help me out and point out where I am making a mistake?










share|improve this question













marked as duplicate by MisterMiyagi, chepner python
Users with the  python badge can single-handedly close python questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 19 at 21:04


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.















  • docs.python-guide.org/writing/gotchas/#late-binding-closures
    – ritlew
    Nov 19 at 20:59













up vote
2
down vote

favorite









up vote
2
down vote

favorite












This question already has an answer here:




  • How do I create a list of Python lambdas (in a list comprehension/for loop)?

    8 answers




I am trying to generate (something like) the following dictionary:



funcs1 = {
'0':lambda x:x==0,
'1':lambda x:x==1,
'2':lambda x:x==2,
'3':lambda x:x==3,
'4':lambda x:x==4,
'5':lambda x:x==5,
}


I tried to create the dictionary with a list comprehension like this:



funcs2 = {str(i):lambda x:x==i for i in range(0,6)}


Or simply using a for loop:



funcs3 = {}
for i in range(0,6):
funcs3.update({str(i): lambda x:x==i})


However, funcs2 and funcs3 are not the same as funcs1, for example, when calling the element '0' of each one of them and applying it to 0, the results are different:



funcs1['0'](0)
Out[2]: True

funcs2['0'](0)
Out[3]: False

funcs3['0'](0)
Out[4]: False


Can somebody please help me out and point out where I am making a mistake?










share|improve this question














This question already has an answer here:




  • How do I create a list of Python lambdas (in a list comprehension/for loop)?

    8 answers




I am trying to generate (something like) the following dictionary:



funcs1 = {
'0':lambda x:x==0,
'1':lambda x:x==1,
'2':lambda x:x==2,
'3':lambda x:x==3,
'4':lambda x:x==4,
'5':lambda x:x==5,
}


I tried to create the dictionary with a list comprehension like this:



funcs2 = {str(i):lambda x:x==i for i in range(0,6)}


Or simply using a for loop:



funcs3 = {}
for i in range(0,6):
funcs3.update({str(i): lambda x:x==i})


However, funcs2 and funcs3 are not the same as funcs1, for example, when calling the element '0' of each one of them and applying it to 0, the results are different:



funcs1['0'](0)
Out[2]: True

funcs2['0'](0)
Out[3]: False

funcs3['0'](0)
Out[4]: False


Can somebody please help me out and point out where I am making a mistake?





This question already has an answer here:




  • How do I create a list of Python lambdas (in a list comprehension/for loop)?

    8 answers








python dictionary lambda list-comprehension






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 19 at 20:53









Juan Manuel Ortiz

154




154




marked as duplicate by MisterMiyagi, chepner python
Users with the  python badge can single-handedly close python questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 19 at 21:04


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.






marked as duplicate by MisterMiyagi, chepner python
Users with the  python badge can single-handedly close python questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 19 at 21:04


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.














  • docs.python-guide.org/writing/gotchas/#late-binding-closures
    – ritlew
    Nov 19 at 20:59


















  • docs.python-guide.org/writing/gotchas/#late-binding-closures
    – ritlew
    Nov 19 at 20:59
















docs.python-guide.org/writing/gotchas/#late-binding-closures
– ritlew
Nov 19 at 20:59




docs.python-guide.org/writing/gotchas/#late-binding-closures
– ritlew
Nov 19 at 20:59












2 Answers
2






active

oldest

votes

















up vote
5
down vote



accepted










This is a common misunderstanding caused by Python late binding, this should fix your code:



funcs1 = {
'0': lambda x: x == 0,
'1': lambda x: x == 1,
'2': lambda x: x == 2,
'3': lambda x: x == 3,
'4': lambda x: x == 4,
'5': lambda x: x == 5,
}

funcs2 = {str(i): lambda x, i=i: x == i for i in range(0, 6)}

funcs3 = {}
for i in range(0, 6):
funcs3.update({str(i): lambda x, i=i: x == i})

print(funcs1['0'](0))
print(funcs2['0'](0))
print(funcs3['0'](0))


Output



True
True
True





share|improve this answer




























    up vote
    0
    down vote













    This works:



    >>> def make_fn(i):
    ... def fn(x):
    ... return x==i
    ... return fn
    ...
    >>> funcs = {str(i): make_fn(i) for i in range(6)}


    Testing, I get:



    >>> funcs['0'](0)
    True
    >>> funcs['1'](1)
    True
    >>> funcs['0'](1)
    False





    share|improve this answer




























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      5
      down vote



      accepted










      This is a common misunderstanding caused by Python late binding, this should fix your code:



      funcs1 = {
      '0': lambda x: x == 0,
      '1': lambda x: x == 1,
      '2': lambda x: x == 2,
      '3': lambda x: x == 3,
      '4': lambda x: x == 4,
      '5': lambda x: x == 5,
      }

      funcs2 = {str(i): lambda x, i=i: x == i for i in range(0, 6)}

      funcs3 = {}
      for i in range(0, 6):
      funcs3.update({str(i): lambda x, i=i: x == i})

      print(funcs1['0'](0))
      print(funcs2['0'](0))
      print(funcs3['0'](0))


      Output



      True
      True
      True





      share|improve this answer

























        up vote
        5
        down vote



        accepted










        This is a common misunderstanding caused by Python late binding, this should fix your code:



        funcs1 = {
        '0': lambda x: x == 0,
        '1': lambda x: x == 1,
        '2': lambda x: x == 2,
        '3': lambda x: x == 3,
        '4': lambda x: x == 4,
        '5': lambda x: x == 5,
        }

        funcs2 = {str(i): lambda x, i=i: x == i for i in range(0, 6)}

        funcs3 = {}
        for i in range(0, 6):
        funcs3.update({str(i): lambda x, i=i: x == i})

        print(funcs1['0'](0))
        print(funcs2['0'](0))
        print(funcs3['0'](0))


        Output



        True
        True
        True





        share|improve this answer























          up vote
          5
          down vote



          accepted







          up vote
          5
          down vote



          accepted






          This is a common misunderstanding caused by Python late binding, this should fix your code:



          funcs1 = {
          '0': lambda x: x == 0,
          '1': lambda x: x == 1,
          '2': lambda x: x == 2,
          '3': lambda x: x == 3,
          '4': lambda x: x == 4,
          '5': lambda x: x == 5,
          }

          funcs2 = {str(i): lambda x, i=i: x == i for i in range(0, 6)}

          funcs3 = {}
          for i in range(0, 6):
          funcs3.update({str(i): lambda x, i=i: x == i})

          print(funcs1['0'](0))
          print(funcs2['0'](0))
          print(funcs3['0'](0))


          Output



          True
          True
          True





          share|improve this answer












          This is a common misunderstanding caused by Python late binding, this should fix your code:



          funcs1 = {
          '0': lambda x: x == 0,
          '1': lambda x: x == 1,
          '2': lambda x: x == 2,
          '3': lambda x: x == 3,
          '4': lambda x: x == 4,
          '5': lambda x: x == 5,
          }

          funcs2 = {str(i): lambda x, i=i: x == i for i in range(0, 6)}

          funcs3 = {}
          for i in range(0, 6):
          funcs3.update({str(i): lambda x, i=i: x == i})

          print(funcs1['0'](0))
          print(funcs2['0'](0))
          print(funcs3['0'](0))


          Output



          True
          True
          True






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 19 at 20:57









          Daniel Mesejo

          11.2k1924




          11.2k1924
























              up vote
              0
              down vote













              This works:



              >>> def make_fn(i):
              ... def fn(x):
              ... return x==i
              ... return fn
              ...
              >>> funcs = {str(i): make_fn(i) for i in range(6)}


              Testing, I get:



              >>> funcs['0'](0)
              True
              >>> funcs['1'](1)
              True
              >>> funcs['0'](1)
              False





              share|improve this answer

























                up vote
                0
                down vote













                This works:



                >>> def make_fn(i):
                ... def fn(x):
                ... return x==i
                ... return fn
                ...
                >>> funcs = {str(i): make_fn(i) for i in range(6)}


                Testing, I get:



                >>> funcs['0'](0)
                True
                >>> funcs['1'](1)
                True
                >>> funcs['0'](1)
                False





                share|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  This works:



                  >>> def make_fn(i):
                  ... def fn(x):
                  ... return x==i
                  ... return fn
                  ...
                  >>> funcs = {str(i): make_fn(i) for i in range(6)}


                  Testing, I get:



                  >>> funcs['0'](0)
                  True
                  >>> funcs['1'](1)
                  True
                  >>> funcs['0'](1)
                  False





                  share|improve this answer












                  This works:



                  >>> def make_fn(i):
                  ... def fn(x):
                  ... return x==i
                  ... return fn
                  ...
                  >>> funcs = {str(i): make_fn(i) for i in range(6)}


                  Testing, I get:



                  >>> funcs['0'](0)
                  True
                  >>> funcs['1'](1)
                  True
                  >>> funcs['0'](1)
                  False






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 19 at 20:59









                  jobevers

                  6221718




                  6221718















                      Popular posts from this blog

                      "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

                      Alcedinidae

                      Origin of the phrase “under your belt”?