Understanding .Get() Method in Python

Understanding .get() method in Python

The get method of a dict (like for example characters) works just like indexing the dict, except that, if the key is missing, instead of raising a KeyError it returns the default value (if you call .get with just one argument, the key, the default value is None).

So an equivalent Python function (where calling myget(d, k, v) is just like d.get(k, v) might be:

def myget(d, k, v=None):
try: return d[k]
except KeyError: return v

The sample code in your question is clearly trying to count the number of occurrences of each character: if it already has a count for a given character, get returns it (so it's just incremented by one), else get returns 0 (so the incrementing correctly gives 1 at a character's first occurrence in the string).

Dont understanding a trick on .get() method in python

The get method on a dictionary is documented here: https://docs.python.org/3/library/stdtypes.html#dict.get

get(key[, default])

Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.

So this explains the 0 - it's a default value to use when letternum doesn't contain the given letter.

So we have letternum.get(each_letter, 0) - this expression finds the value stored in the letternum dictionary for the currently considered letter. If there is no value stored, it evaluates to 0 instead.

Then we add one to this number: letternum.get(each_letter, 0) + 1

Finally we stored it back into the letternum dictionary, although this time converting the letter to lowercase: letternum[each_letter.lower()] = letternum.get(each_letter, 0) + 1 It seems this might be a mistake. We probably want to update the same item we just looked up, but if each_letter is upper-case that's not true.

Understanding __getitem__ method

Cong Ma does a good job of explaining what __getitem__ is used for - but I want to give you an example which might be useful.
Imagine a class which models a building. Within the data for the building it includes a number of attributes, including descriptions of the companies that occupy each floor :

Without using __getitem__ we would have a class like this :

class Building(object):
def __init__(self, floors):
self._floors = [None]*floors
def occupy(self, floor_number, data):
self._floors[floor_number] = data
def get_floor_data(self, floor_number):
return self._floors[floor_number]

building1 = Building(4) # Construct a building with 4 floors
building1.occupy(0, 'Reception')
building1.occupy(1, 'ABC Corp')
building1.occupy(2, 'DEF Inc')
print( building1.get_floor_data(2) )

We could however use __getitem__ (and its counterpart __setitem__) to make the usage of the Building class 'nicer'.

class Building(object):
def __init__(self, floors):
self._floors = [None]*floors
def __setitem__(self, floor_number, data):
self._floors[floor_number] = data
def __getitem__(self, floor_number):
return self._floors[floor_number]

building1 = Building(4) # Construct a building with 4 floors
building1[0] = 'Reception'
building1[1] = 'ABC Corp'
building1[2] = 'DEF Inc'
print( building1[2] )

Whether you use __setitem__ like this really depends on how you plan to abstract your data - in this case we have decided to treat a building as a container of floors (and you could also implement an iterator for the Building, and maybe even the ability to slice - i.e. get more than one floor's data at a time - it depends on what you need.

Understanding __get__ and __set__ and Python descriptors

The descriptor is how Python's property type is implemented. A descriptor simply implements __get__, __set__, etc. and is then added to another class in its definition (as you did above with the Temperature class). For example:

temp=Temperature()
temp.celsius #calls celsius.__get__

Accessing the property you assigned the descriptor to (celsius in the above example) calls the appropriate descriptor method.

instance in __get__ is the instance of the class (so above, __get__ would receive temp, while owner is the class with the descriptor (so it would be Temperature).

You need to use a descriptor class to encapsulate the logic that powers it. That way, if the descriptor is used to cache some expensive operation (for example), it could store the value on itself and not its class.

An article about descriptors can be found here.

EDIT: As jchl pointed out in the comments, if you simply try Temperature.celsius, instance will be None.

Understanding dictionary.get in Python

The key argument to sorted is a callable (e.g. a function) which takes one argument.

By default, sorted sorts the values by comparing them to each other. For example:

sorted([2, 3, 1])   # returns [1, 2, 3]

This is because 1 < 2 < 3.

On the other hand, if a different value should be used for comparison, that can be defined with key. For example, to sort strings by length, one coudld do:

def string_length(s):
return len(s)

sorted(['abcd', 'efghi', 'jk'], key=string_length) # returns ['jk', 'abcd', 'efghi']

This is because string_length('jk') < string_length('abcd') < string_length('efghi').

But instead of a funcion, you can pass any other callable. In your example, that is dict1.get, so for each key in the dict, dict1.get(key) will be executed and the result of that will be used in comparison.

dict1 = {'a':3, 'b':1, 'c':2}

sorted(dict1, key=dict1.get) # returns ['b', 'c', 'a']

This is because dict1.get('b') < dict1.get('c') < dict1.get('a').

What's the difference between the method .get() and the method .get in python? Both are appliable to dictionaries

A method is literally just an attribute of an object that happens to be of type <class function>. The output you see is essentially what happens when you try to call print() on any function object, and is essentially a concise string representation that python creates for the function.

Actually calling a function is done with parentheses: d.get('a'), which means to execute the behavior the function refers to. It doesn't especially matter where the function is, though: I could do the following, and it would still work:

d = {'a': 1 , 'b':3}
freefunc = d.get
freefunc('a')

This is what the term "first class functions" refers to, when people compare python to something like Java. An entire function can be encapsulated in a variable and treated no differently than any other variable or attribute.

Finding what methods a Python object has

For many objects, you can use this code, replacing 'object' with the object you're interested in:

object_methods = [method_name for method_name in dir(object)
if callable(getattr(object, method_name))]

I discovered it at diveintopython.net (now archived), that should provide some further details!

If you get an AttributeError, you can use this instead:

getattr() is intolerant of pandas style Python 3.6 abstract virtual sub-classes. This code does the same as above and ignores exceptions.

import pandas as pd
df = pd.DataFrame([[10, 20, 30], [100, 200, 300]],
columns=['foo', 'bar', 'baz'])
def get_methods(object, spacing=20):
methodList = []
for method_name in dir(object):
try:
if callable(getattr(object, method_name)):
methodList.append(str(method_name))
except Exception:
methodList.append(str(method_name))
processFunc = (lambda s: ' '.join(s.split())) or (lambda s: s)
for method in methodList:
try:
print(str(method.ljust(spacing)) + ' ' +
processFunc(str(getattr(object, method).__doc__)[0:90]))
except Exception:
print(method.ljust(spacing) + ' ' + ' getattr() failed')

get_methods(df['foo'])

Why dict.get(key) instead of dict[key]?

It allows you to provide a default value if the key is missing:

dictionary.get("bogus", default_value)

returns default_value (whatever you choose it to be), whereas

dictionary["bogus"]

would raise a KeyError.

If omitted, default_value is None, such that

dictionary.get("bogus")  # <-- No default specified -- defaults to None

returns None just like

dictionary.get("bogus", None)

would.

Python using dict .get() method where value = 0

1 != '1'; an int isn't equal to a str.

>>> x = {1:0}
>>>
>>> print x.get('1', 'a')
a
>>> print x.get(1, 'a')
0


Related Topics



Leave a reply



Submit