2

I'm trying to store a function in python dictionary that minipulates some ranges from the dictionary it self, but I don't how to pass self to the function, ex:

d = {"r": range(10), "r2": range(10, 20), "f": lambda self: self["r"].extend(self["r2"])}

I expect it to return extended list like: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

but when I call d["f"]() I get TypeError: <lambda>() takes exactly 1 argument (0 given).

even when I do d["f"](d) I get nothing !

>>> d["f"](d)
>>>

so is it even possible ? and how ? thank in advanced.

UPDATE 1

I want to pass self to the dictionary to filter the some values within the dictionary, and classing is not an option because my case is to use that in google-app-engine here's my question about that

so classing won't work (I've got to this because I can't store classes in datastore so I use subclassed dictionaries instead see my other question above)

Community
  • 1
  • 1
M-Dahab
  • 389
  • 7
  • 11

2 Answers2

4

Your second usage, d["f"](d), is correct.

However, list.extend does not return anything - so you don't see anything in the terminal. It is, however, extending the list:

>>> x = [1, 2, 3]
>>> x.extend([4, 5]) # nothing is returned here
>>> x
[1, 2, 3, 4, 5]

Also, you should avoid calling the parameter to the function self - it has other purposes when using classes.


It seems that your need is a perfect use case for a class of this form:
class MyData:
    def __init__(self):
        self.r = range(10)
        self.r2 = range(10, 20)

    def f(self):
        self.r.extend(self.r2)
        return self.r

To use it:

d = MyData()
d.f() # prints out your expected result
Rushy Panchal
  • 16,979
  • 16
  • 61
  • 94
  • that's correct thank you, but shall I pass the whole dictionary to the function to get it to work ?!! – M-Dahab May 08 '16 at 04:43
  • 2
    @user5258689 You might want to look into using classes - you'll be able to accomplish what you want in a much simpler (and Pythonic) way. – Rushy Panchal May 08 '16 at 04:46
2

Use a closure - the function that remembers its environment. You don't need to pass anything into d["f"], all the information can be already present:

def make_d():
    d = {"r": range(10), "r2": range(10, 20), "f": lambda: d["r"].extend(d["r2"])}
    return d

the_d = make_d()
the_d["f"]()
the_d
# => {'r': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], 'r2': [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], 'f': <function <lambda> at 0x105c76c80>}

Rushy is correct though: this is a literal solution to your problem, and using classes properly would likely make this a non-issue (but of course YMMV).

Amadan
  • 191,408
  • 23
  • 240
  • 301
  • that's quite useful thank you, the problem is that I want this to work in google-app-engine with some issues from this question here: http://stackoverflow.com/questions/36983340/how-to-subclass-google-app-engine-ndb-property-to-support-python-subclassed-obje – M-Dahab May 08 '16 at 04:50