3

With (some) Pythons built-in types, is it possible to refer to the object we are declaring ? By "(some) built-in types" I think about, for example, sequence types, mapping types or set types, obviously not numeric types.

I mean, without creating a class myself and adding this functionality (without creating a subclass).

So, something like the this keyword as used in the examples below.

For example, for the "dict" Python built-in type, something like this:

a_dictionary = {
    "key_1": "value_1",
    "key_2": "value_2",
    "key_3": this["key_1"] + "_" + this["key_2"] # == "value_1_value_2"
}

or even:

a_dictionary = {
    "sub_dict_1": {
        "key_1": "value_1_1",
        "key_2": "value_1_2",
        "key_3": this["key_1"] + "_" + this["key_2"] # == "value_1_1_value_1_2"
    },
    "sub_dict_2": {
        "key_1": "value_2_1",
        "key_2": "value_2_2",
        "key_3": this["key_1"] + "_" + this["key_2"] # == "value_2_1_value_2_2"
    }
}

I've read :

When doing function chaining in python, is there a way to refer to the "current" object?

What do I do when I need a self referential dictionary?

Reference a dictionary within itself

Self-referencing classes in python?

Is there a way to refer to the current function in python?

Is it possible to access current object while doing list/dict comprehension in Python?

and some others, but it doesn't match up the requirements described at the begining of my question.

Thanks a lot for your help!

Rivers
  • 1,783
  • 1
  • 8
  • 27
  • 2
    How about this killer approach? `a_dictionary = {"key_1": "value_1", "key_2": "value_2"}; a_dictionary["key_3"] = a_dictionary["key_1"] + "_" + a_dictionary["key_2"]` – VisioN Oct 14 '20 at 14:53
  • Does this answer your question? [Is it possible to access current object while doing list/dict comprehension in Python?](https://stackoverflow.com/questions/21112814/is-it-possible-to-access-current-object-while-doing-list-dict-comprehension-in-p) – Tomerikoo Oct 14 '20 at 14:54
  • 1
    IMO, what you're asking for is a strange quirk of JS that can make code more confusing, Python is a different beast and it's better to create a class if you need some specialized behavior like this – Alex W Oct 14 '20 at 14:55
  • ... Or just find other readable Pythonic alternatives to get the same result... – Tomerikoo Oct 14 '20 at 14:57
  • @Tomerikoo It ressembles, but no it does'nt answers my question. Thank you for pointing this post. I'll add this link to my question! – Rivers Oct 14 '20 at 15:00
  • @ VisioN The goal is not to create a third key that would be the concatetnation of keys 1 and 2 plus a "_" in the middle. The question is really about referring to the object itself. But yes, your solution works if the goal is the concatenation. Thanks. – Rivers Oct 14 '20 at 15:05
  • @Alex W Indeed I agree, I was thinking the same when this questionned me, but I just wanted to know if it exists or not, I'm not asking to add this to Python if not existing :-) – Rivers Oct 14 '20 at 15:09

2 Answers2

8

Python provides no way to refer to an object under construction by a literal or a display*. You can (ab)use the assignment expression in Python 3.8 or later to simulate this:

a_dictionary = {
    "key_1": (x := "value_1"),
    "key_2": (y := "value_2"),
    "key_3": x + "_" + y 
}

It requires some planning ahead, as you are not referring to a key value directly, rather a pre-defined variable. Notice that x and y remain in scope after the assignment to a_dictionary, so this is just a questionable equivalent of

x = "value_1"
y = "value_2"
a_dictionary = {
    "key_1": x,
    "key_2": y,
    "key_3": x + "_" + y
}

A custom class would really be more appropriate:

class Thing:
    def __init__(self, v1, v2):
        self.key_1 = v1
        self.key_2 = v2
        self.key_3 = v1 + "_" + v2


a_thing = Thing("value_1", "value_2")

  • A display is a construct like a literal, but could contain non-literal references. For example, list displays include [1, x, y] and [int(x) for x in foo].
chepner
  • 497,756
  • 71
  • 530
  • 681
  • That's an interesting answer. Do you know if there's an official source for "Python provides no way to refer to an object under construction by a literal, view or comprehension" ? – Rivers Oct 14 '20 at 15:36
  • 2
    As a negative, it's hard to find an explicit statement of the fact. There are *lots* of things that Python doesn't provide; they aren't enumerated in the documentation. – chepner Oct 14 '20 at 15:54
0

After some digging, and only for the case of a dictionary, I found this other workaround, based on What do I do when I need a self referential dictionary? :

class MyDict(dict):
    def __getitem__(self, item):
        return dict.__getitem__(self, item).format(self)

a_dictionary = MyDict({
    "key_1": "value_1",
    "key_2": "value_2",
    "key_3": "{0[key_1]}" + "_" + "{0[key_2]}" # == "value_1_value_2"
})
Rivers
  • 1,783
  • 1
  • 8
  • 27