Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Use of Indexing Operator
#1
Hi Everyone

I'm struggling to understand the use of the indexing operator ([]) in the code snippet below (it is an extract from a class definition).
Could you explain the meaning of the "[]" used in this context?
Can you point me to documentation which explains this?


graph_dict = dict(
    Arad=dict(Zerind=75, Sibiu=140, Timisoara=118),
    Bucharest=dict(Urziceni=85, Pitesti=101, Giurgiu=90, Fagaras=211),
    Craiova=dict(Drobeta=120, Rimnicu=146, Pitesti=138),
    Drobeta=dict(Mehadia=75),
    Eforie=dict(Hirsova=86),
    Fagaras=dict(Sibiu=99),
    Hirsova=dict(Urziceni=98),
    Iasi=dict(Vaslui=92, Neamt=87),
    Lugoj=dict(Timisoara=111, Mehadia=70),
    Oradea=dict(Zerind=71, Sibiu=151),
    Pitesti=dict(Rimnicu=97),
    Rimnicu=dict(Sibiu=80),
    Urziceni=dict(Vaslui=142))

for a in list(self.graph_dict.keys()):
            for (b, dist) in self.graph_dict[a].items():
                self.connect1(b, a, dist)

def connect1(self,A, B, distance):
        self.graph_dict.setdefault(A, {})[B] = distance
Much appreciated
Reply
#2
For indexing a list you have an integer in the brackets. For "indexing" a dictionary you have a key in the brackets. Is that your question?

https://docs.python.org/3/tutorial/datas...ctionaries
Reply
#3
(Feb-19-2022, 10:29 PM)deanhystad Wrote: For indexing a list you have an integer in the brackets. For "indexing" a dictionary you have a key in the brackets. Is that your question?

https://docs.python.org/3/tutorial/datas...ctionaries

Hi
No, that is not the question. I understand how the indexing operator is used to reference values.
But, the use of the operator as part of a method or function call confuses me.
here it's used as:
some_method(method parameters)[a value]

Could you explain what the meaning of the above line would be?
Reply
#4
It means that some_method() returns an indexable object such as a dict or a list, etc, so this is equivalent to
d = some_method(method parameters)
d["a value"]
Reply
#5
(Feb-20-2022, 10:31 AM)PythonNewbee Wrote: some_method(method parameters)[a value]
The returned value of some_method(method parameters) is apparently a dictionary. So you can immediately address one item of that dictionary.
Reply
#6
It is always a good idea to start from documentation.

>>> help(dict.setdefault)
Help on method_descriptor:

setdefault(self, key, default=None, /)
    Insert key with a value of default if key is not in the dictionary.

    Return the value for key if key is in the dictionary, else default.
So graph_dict.setdefault(A, {})[B] = distance can be translated:

- check whether key in dictionary, if not add key with default value (in this case empty dictionary)
- return value of key (existing value or default value set in previous step)


As graph_dict.setdefault(A, {}) returns value of key A (existing or default) it is possible to add new key-value pair to it as usally (like graph_dict['B'] = distance) difference being that previous setdefaultensures that there is existing dictionary as value to the key.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#7
This returns an object that is indexable.
self.graph_dict.setdefault(A, {})
This indexes that object using B as the index.
self.graph_dict.setdefault(A, {})[B]
You have to "think" Python and look at how the parts of this statement work.

"self". This must be code inside an instance method. self is a variable that references an instance of the class. By convention, "self" should never be used as a variable name except as the first argument in an instance method, and as the variable used to reference the instance in the code of an instance method.

"self.graph_dict". graph_dict must be an attribute of the object. I don't know if the attribute is a method or a variable.

"self.graph_dict.setdefault". Now I know that "graph_dict" is not a method. If it was a method it would be followed by "()" instead of ".". "graph_dict" is an instance (or possibly a class) variable, and "setdefault" is an attribute of whatever "self.graph_dict" is.

"self.graph_dict.setdefault(A, {})". Now we know that setdefault is a method. We call this method and pass "A" and and empty dictionary as arguments.

"self.graph_dict.setdefault(A, {})[B]". "setdefault" is a method and now we know it returns something other than None. Whatever it returns is indexable. It could be a dictionary. It could be a list. I cannot tell by only looking at this code.
Reply
#8
(Feb-20-2022, 02:56 PM)deanhystad Wrote: This returns an object that is indexable.
self.graph_dict.setdefault(A, {})
This indexes that object using B as the index.
self.graph_dict.setdefault(A, {})[B]
You have to "think" Python and look at how the parts of this statement work.

"self". This must be code inside a class method. self is a variable that references an instance of the class. By convention, "self" should never be used as a variable name except as the first argument in an instance method, and as the variable used to reference the instance in the code of an instance method.

"self.graph_dict". graph_dict must be an attribute of the object. I don't know if the attribute is a method or a variable.

"self.graph_dict.setdefault". Now I know that "graph_dict" is not a method. If it was a method it would be followed by "()" instead of ".". "graph_dict" is an instance (or possibly a class) variable, and "setdefault" is an attribute of whatever "self.graph_dict" is.

"self.graph_dict.setdefault(A, {})". Now we know that setdefault is a method. We call this method and pass "A" and and empty dictionary as arguments.

"self.graph_dict.setdefault(A, {})[B]". "setdefault" is a method and now we know it returns something other than None. Whatever it returns is indexable. It could be a dictionary. It could be a list. I cannot tell by only looking at this code.

Ah! Thank you Dean, your explanation pointed out a misunderstanding I had and cleared it up for me.

Would you mind helping me with another question?

Referring to this code (an implementation of a hill-climbing algorithm):
def hill_climbing(problem):
    """
    [Figure 4.2]
    From the initial node, keep choosing the neighbor with highest value,
    stopping when no neighbor is better.
    """
    current = Node(problem.initial)
    while True:
        neighbors = current.expand(problem)
        if not neighbors:
            break
        neighbor = argmax_random_tie(neighbors, key=lambda node: problem.value(node.state))
        if problem.value(neighbor.state) <= problem.value(current.state):
            break
        current = neighbor
    return current.state


I'm not understanding the "While True:" statement.
This loop runs while what is true?
Could this statement be rewritten to provide more clarity on its meaning?
Is it linked to the value of the variable current?
Reply
#9
This is a common way to implement a loop where the exit condition is not known or inconvenient to calculate or code. In your example you want to exit the loop if neighbors is Falsy (Null, 0, iterable with len 0), or if the current neighbor's state <= the previous neighbors state. It would be very difficult to put these in the loop condition at the top, so you loop forever and break out when one of the conditions occurs. Once you are used to seeing "while True" I think it is much cleaner and clearer than trying to put complicated condition code up next to the "while".
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How to change 0 based indexing to 1 based indexing in python..?? Ruthra 2 4,328 Jan-22-2020, 05:13 PM
Last Post: Ruthra

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020