Difference between notations

Hello. Would you prompt me, what is the difference between this: ‘avg_order[‘price’]’, and this: ‘avg_order.price’ notation?

Sometimes one of them doesn’t work, whereas another does.

Thank you.

those are two very different things, print(avg_order['price']) is a key lookup, so when avg_order is a dictionary:

avg_order = {'price': 5}
print(avg_order['price'])

while avg_order.price is used to access a property of a class:

class Order:
    def __init__(self, price):
        self.price = price

order = Order(5)
order.price 

so which syntax very much depends on the data type

3 Likes

Thank you very much. It became much clear.

Would you, please, explain me in detail when we should use each of both notations. As far as I can tell on the basis of your reply: ['price'] - notation is used with dictionary type, while .price - notation is used with object type.

In this lesson:

students.score = students.score.replace('[\%,]', '', regex=True)
students.score = pd.to_numeric(students.score)

print(type(students.score))
print(type(students['score']))

gives the same types:

>>><class 'pandas.core.series.Series'>
>>><class 'pandas.core.series.Series'>

and notation doesn’t matter. Both notations work.
The only difference I found: it’s possible to create new columns in DF only via ['column'] notation.

i have never used panda, but lets do a simple example:

class Test:
    abc = 'Hello world'
    def __getitem__(self, key):
        return getattr(self, key)

test = Test()
print(test.abc)
print(test['abc'])

__getitem__ is a magic method we implement to do dictionary lookup. So pandas Series class must have implemented this method as well.

so under the hood, when you do ['score'], the __getitem__ magic method gets called. Data types like dictionaries are also classes, and implement these methods.

this also enables us to make our own classes, for example MultiDict, might the need ever arise to have a dictionary where the same key can occur multiple times.

1 Like

Thank you. If I understood you right:
-['attribute'] notation calls attribute value via getitem (which looks up in the dictionary)
-.attribute notation calls attribute value directly from class

no, __getitem__ gives dictionary like behavior. Dictionaries also have this method implemented.

1 Like

The [] operator asks the object to look up a value by the key you give it.
The . operator asks the object to return an attribute by the name you give it.

So, yes, they kind of do the same thing, they’re mainly different by convention. The object decides what it does when it receives those requests, and as you have found, pandas dataframes expose the same things through both of them, presumably so that programmers can use whatever happens to come to mind as they’re typing.

Typically the . operator is for something concerning the structure of the program, while [] is for data stored by the object. For example, a method would be accessed through ., not through []

>>> 'hello'.capitalize()
'Hello'
>>> 'hello'['capitalize']()
some kind of error, the string expected an integer through [], an index

And I expect you’ll find that dataframe methods are accessed through . while remaining unavailable through []

. 's right operand isn’t a value at all, it’s a hard-coded name. This makes [] more suitable if the key isn’t known when the program is written. It’s still possible to access that behaviour with a string (through getattr) but that’s really just saying that [] should be used instead.

You could similarly use the call operator () for lookup, and probably some other things too. No matter how you interact with an object, it’s up to the object to interpret the meaning of it, this isn’t something python enforces it’s more like a message sent to the object that it can respond to however it sees fit. Ideally the object’s behaviour matches that of what those operators mean for other types of values.

1 Like

Thank you. 3 insites I got from your letter:

  1. don’t worry too much, what operator to use if it works (althought, it will be interesting to measure the program’ execution time in both cases)
  2. . operator is less flexible and is used when we know exactly the address
  3. only . operator can be used to call methods