Some Magnificent Functions In Python 3.9 | by Emmett Boudreau | Towards Data Science

The Python programming language comes packed full of many fantastic functions and tools in the language itself, as well as some awesome abilities that are available in the standard library. This makes Python quite a versatile language on its own without needing to rely on dependencies nearly as much as some other languages that use dependencies a lot more across the board. In the past, I have discussed some of my favorite Python modules that are contained inside of the standard library in the past, and if you would like to read into some articles where I do so, you can check out my last article on this topic here:
towardsdatascience.com
However, despite the usefulness of these tools, there is still more fun to be had with the actual language itself. There are so many very useful functions that are included inside of the Python programming language off the bat that can be incredibly useful in many different scenarios. This is especially true for Data Scientists, as many of these operations work really well on iterative lists of observations.
notebook
The map function applies a given function to each element of an iterable. This can be incredibly useful in order to process lists very quickly and efficiently without ever having to write a for loop. We will use map() on the following list:
lst = [5, 10, 15, 20]
Next we must make a function that we would like each element to be passed through. An important thing to remember is that we will only be able to take one positional argument without a default, otherwise the map will not work!
def addone(x):    return(x + 1)
In my example, I am simply adding one to each element of my list, but you could certainly get pretty complex with these functions if you desired to do so. The biggest hindrance here is most certainly going to be not being able to add parameters. However, you could always call extracted methods externally from within your mapped function to get data you might need. Other than that, you will be relying on the defaults set forth in your function. Now we will create a new map using:
lstpone = map(addone, lst)
You will notice that the type of this new object will likely come out as a map class. In order to change this, we can simply cast an according type onto our map, such as list:
lstpone = list(map(addone, lst))print(lstpone)
It is easy to see where something like this could potentially come in handy to handle data in Python. Just as well, it is far cleaner and more concise to write an extracted map() function than it is to have some nested for loop to perform arithmetic. I wrote a neat article on extraction, and why it is such a great practice as a programmer that is certainly worth a read if you are interested in such a concept that will go into far more detail on this topic that you may view here if you desire:
towardsdatascience.com
Another really cool function that comes with Python is the zip() function. Most Python programmers have likely had experience with this function, but it is certainly worth mentioning for those who have not utilized this powerful function before. The zip function creates a new iterator out of multiple iterables and allows one to iterate over multiple elements of different lists at the same time in the same cycle. Needless to say, this is incredibly useful for things like comparing two groups, or performing some level of arithmetic on features.
We will be using the following lists for this example:
lst1 = [23, 28, 43, 23, 23, 94, 32]lst2 = [34, 58, 109, 72, 33, 2, 90]lst3 = []
We will be getting a list of means between each matching element by zipping these two together and then calculating the means at each cycle before appending the new mean to our empty list, lst3. Firstly, however, we will need to write a function to calculate our mean:
def mu(x):    return(sum(x) / len(x))
Now we will write a simple for loop using the zip() function like so:
for one, two in zip(lst1, lst2):    lst3.append(mu([one, two]))print(lst3)
It is easy to see why something like this could be valuable for working with data. Iterating across multiple features is a scenario that you could very easily find yourself in, so this solution is certainly a great idea. I happen to have a much more in-depth article that is all about Python’s zip() function that is certainly worth checking out if you have never seen this before, you may view it here:
towardsdatascience.com
The super() function is another very useful feature in the base of the Python programming language. This function is much more Pythonic than the other two, and allows for sub-classes to reference their parents as “ super.” The first reason why this is useful is that we can avoid using the base class explicitly, in other words we can control whether we are referencing the parent class or the child class. Another place where this comes in handy is when we work with multiple sub-classes and a lot of inheritance. Let us consider the following class:
class Noodle(object):    def __init__(self, name):        print(name)
This class inherits from object, as do all other classes in Python. Let us now make a sub-class for this new Noodle type:
class Spaghetti(Noodle):    def __init__(self):        pass
In this first example, we only use pass in this class’s initialization function. Since this class is spaghetti, we do not want to have to label it as spaghetti, but we still want it to print out spaghetti when we initialize it. In order to print its name without any work at all in this circumstance, we can call the super function inside of our initialization function and call the initialization of our parent as well.
super().__init__("Spaghetti")
Notice that now both classes will print their names when initialized, which would not be the case without this call. Of course, this is not the only single-inheritance circumstance where this is a useful function to be aware of. This function can certainly come in handy in many different scenarios, so it is definitely worth getting acquainted with!
The hash() function is used to return the hash value of an object in Python. Wow this is a relatively easy method to use, I thought it was worth including because sometimes it is interesting to look at. A hash will be a signed integer that is used to express that given value. The function takes an object as an argument, for example the string “ Hello”:
print(hash(“ Hello”))-7944160827638463773
The format method can be used to return a formatted representation of an object that is controlled by a format specifier. These methods call the internal __format__() function of an object. This method takes two arguments, the first of which is the value we would like to format, the second of which is the format specifications. For a full list of specifiers, you can check out this page:
pyformat.info
Anyway, in this example I am just going to turn a signed integer into binary:
print(format(1392391237, "b"))1010010111111100011010001000101
I know I said signed integer earlier, but this integer appears to either be excluding the sign, or be unsigned. We can tell this by casting it to a list and then dividing the length by 8:
print(len(list(format(1392391237, "b"))) / 8)3.875
Of course, if this were the real binary for the number, it would be divisible by 4, so I think that Python’s format is just leaving the sign portion of this binary out, which is something to note — that is strange.
A very useful tool when it comes to looping in Python is the enumerate() function. This function can be used to easily add a counter to a loop in one simple call. This can be useful for labeling dictionaries, calling indexes, all kinds of things! And allows you to do so without making a counter outside the loop and adding to it. We could use it to accomplish essentially the same thing as a zip loop, for example:
for i, w in enumerate(lst1):    lst2[i] += w
This will modify the index we are enumerating with addition to the current iteration in our lst1 list.
print(lst2)[57, 86, 152, 95, 56, 96, 122]
Have you ever been curious about how a computer actually stores data? You can learn more about just that by checking out the memoryview() function in Python! This will allow us to view a byte-buffer that is representative of the characters in our Python object. Consider the following string:
lstmem = memoryview(bytearray(lst2, "utf-8"))print(list(lstmem))[104, 101, 108, 108, 111, 33]
These are the individual representations of the chars in this string placed into a list. This might sound useless, but it could be used to make a float encoder. However, you could always just cast the float type. Regardless, I think this is a pretty interesting and cool method!
Python has become an essential asset for Data Science work over the past couple years, and this is for good reason. While Python certainly does have its short comings, it has a strong ecosystem, a venerable code-base, and even a fantastic standard library. These are some pretty simple and well-known Python functions, but I think especially for beginners, or those that wanted to know a bit more about some of these sorts of functions this article could certainly come in handy. Thank you so much for reading my article!