Started with a new Reuven Lerner Course, on Advanced Data Structures..
Aiming to comfortably finish this in a week.
Notes and experiences, follow.
The course is three parts.
- Part 1 - Deep dive into the common data structures
- Part 2 - Combining Data Structures. Lists of lists, Dicts of lists, Tuples of Lists and so forth. How far can I go without classes? Or how can I enhance my classes with this approach?
- Part 3 - Complex data structures, that come with the Python Standard Library. The Collections module, Weak references etc.
Notes
Part 1
- The
id
of a variable shows me where the object in refers to, is located in memory.
Ifx=5
then theid(x)
will point to where it’s object, here the number 5, is located in memory. - When I assign a variable to another, what I actually do is assign the new variable to the same objects address. That is all. When I do
x = y
, then y will point to 5 too, independent of x. If I set x to something else later, y is not going to follow x. Instead it steadfastly points to 5. - A simple way to say this is
x is y
, where I am not checking for equality, but rather testing the fact, that both of them point to the same location in memory, or not. - I can use
sys.getsizeof()
to find the size of an object in memory. (how much memory it uses), but it’s a tricky beast. For e.g. when it shows me the size of a list, it shows me the size of the list object. Not the size of the elements it contains. To get that, I need to go check the size of its elements one by one. - A singleton object (not many in Python) is an object that every time you create a new instance of, from the parent class, it always points back to the same instance.
None
is an example in Python. - Better to create a list using square brackets, rather than assigning them via a string.
x = ['a','b','c','d']
works better than goingx = list('abcd')
. This obviously matters upon what you are doing and if that is possible to do or not. - I can tuple-unpack-split a string in various ways. If I go,
a, b, *c = s.split[]
it will get the first split item in a, the next one in b, and the rest will be a list in c. But if I want the first and last elements for example and don’t care about the stuff in the middle, I can also go,a, *b, c = s.split()
. I need to play with this. Just realised I could’ve solved a lot of exercises I did in the past, more elegantly if I knew this then. - If I access an element in a sequence via its index, I will get the element back along with the elements type, but if I slice a sequence to get just one element back, I get a single element of the sequence’s type. Very nifty!
- For example if I access
s[0]
in the list['jason', 'braganza']
, then I will get a stringjason
back. - But if I slice and get just the first element with a
s[:1]
(get upto, but not including 1), I get a single element list,['jason']
back.
- For example if I access
- If I look up a key
z
in a dictionaryd
with ad[z]
and it does not exist, then I get aKeyError
. If I want to check keys without noise, I use theget
method on a dictionary. If the key exists, the value is returned. If notNone
comes back.- I can set keys similarly with the
setdefault
key if I want to set keys safely. If I just dod[z] = 100
and z already existed, its value would have gotten trampled and set to 1000. But if I do the samething with ad.setdefault(z, 100)
then it sets it to 100 only if the key does not exist. If it does, it just returns the old existing value. No harm, no foul.
- I can set keys similarly with the
- If I have two dictionaries and I want the contents of one in the other, then I use the update method. For e.g., I have dictionary a and dictionary b, so I do
a.update(b)
and everything from b flows into a.- If there is overlap in the keys, then the values get trampled and overwritten.
- I normally cannot add dictionaries, lists, or other sets to my sets (no unhashable types allowed), I can freeze a set with
frozenset
, which makes it hashable and then add it to my set.
Learning / Feedback/ Experiences from doing exercises
- Reuven makes Python sound like a cute animated bear. ‘Python notices and says “Oh, you’re using 256. I’ve aleady got that. Don’t create a new object for that!”’ I wish my interpreter was as helpful 😂
- This course is a lot less structured than the basic courses. It approaches you from the point of view, that you know stuff, you can read and write Python, you have a modicum of intelligence, so here’s a really juicy grab bag of interesting stuff about all the basics you learnt earlier.
- It’s best to always use f-strings, but if you need to eke performance, can you figure out, what kind of strings are the best? (spoiler, benchmark it)
- While Python lists are expandable, the C structures underyling it are fixed. How does Python let you have flexible, expandable lists then?
- And so on and so forth. So far, this has been fascinating.
Read all about my Python advanced data structures journey here