As you continue to specialize in Python, you’ll no doubt begin to develop a deep understanding of the core libraries that you use the most. For example, the more you use Pandas the more familiar you will become with its core functions, and especially the one’s you use the most often. But one area that is often overlooked is right under your nose: the core “built-ins” – those functions and constants that are always available to you in the language. In this post, I’ll remind you what you might be missing, and it might surprise you what is actually there that is useful to you.
So what is a “built-in”?
Nearly every programming language provides a set of functions and constants that are available to you at all times without importing anything. These built-ins vary from language to language, but there is usually good reason to have an understanding of what they are. Python is no exception, and more importantly, there are some really useful characters in the built-in cast and crew of Python 3.
Why built-ins?
Many built-ins are designed to provide access to some globally useful core function of the language. For example, print()
is a function that nearly everyone has used (and will continue to use) in nearly any context. Similarly, if you’re going to do any kind of file I/O, you will most certainly use the open()
function to open files. In the remainder of this entry, we’ll explore some other built-ins you might want to become familiar with.
A few useful Python built-ins …
Numeric built-ins: sum()
, min()
, max()
, round()
, abs()
Though you may be compelled to use the math
library for numeric functions (and in a lot of cases you should), you probably knew that the built-in range(start, stop [, step])
is a built-in generator, that produces an iterable of numbers (integers) in the range start
to stop
.
But going one step further, the built-in sum()
can be used to to sum up all those numbers generated by range()
(or any others that you’d like that are iterable). You can use min()
and max()
to do the obvious as well.
Again, if you really don’t need to use math
for your work, and just need to do some rounding of a number, use round(number[, ndigits])
to round a number to the nearest multiple of 10 with ndigits
of precision. Finally, try using the very accessible abs()
to get the absolute value of a number.
Iterable built-ins
An iterable is a any Python object that implements the iterator methods that allow looping (iterating), but more specifically implements the __iter__()
method which returns an Iterator
— or an object that supports iteration. The returned Iterator
object implements a next()
method which can be used as the target of looping methods like for .. in [iterable]:
which is also called iterating.
If that sounds confusing, let’s take a look at some of the built-ins to get a feel for what’s really going on.
enumerate()
Ever want to get a list and the corresponding index of the items in that list without doing the counting yourself? enumerate()
might just be what you were needing.
Let’s say you have list, enumerate
that list and you will get a list of tuples, the first value of the tuple is the index (count from 0) and the second value the original list value:
>>> l = ['a', 'b', 'c']
>>> list(enumerate(l))
[(0, 'a'), (1, 'b'), (2, 'c')]
This might be useful if you wanted to get the i th object in a list, without keeping track of a counter yourself.
filter(function, iterable)
Say you have a function which returns True
or False
, for example a function that determines if a number is divisible by 6:
def divisible_by_6(n):
return (n%6)==0
Now let’s say we want to filter all numbers between 1 and 1000 which are divisible by 6 … filter()
is going to do the trick. We simply pass in the function divisible_by_6
and the iterable — in this case the numbers from 1 to 1000.
>>> list(filter(divisible_by_6, range(1,1000)))
[6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108, 114, 120, 126, 132, 138, 144, 150, 156, 162, 168, 174, 180, 186, 1
92, 198, 204, 210, 216, 222, 228, 234, 240, 246, 252, 258, 264, 270, 276, 282, 288, 294, 300, 306, 312, 318, 324, 330, 336, 342, 348, 354, 3
60, 366, 372, 378, 384, 390, 396, 402, 408, 414, 420, 426, 432, 438, 444, 450, 456, 462, 468, 474, 480, 486, 492, 498, 504, 510, 516, 522, 5
28, 534, 540, 546, 552, 558, 564, 570, 576, 582, 588, 594, 600, 606, 612, 618, 624, 630, 636, 642, 648, 654, 660, 666, 672, 678, 684, 690, 6
96, 702, 708, 714, 720, 726, 732, 738, 744, 750, 756, 762, 768, 774, 780, 786, 792, 798, 804, 810, 816, 822, 828, 834, 840, 846, 852, 858, 8
64, 870, 876, 882, 888, 894, 900, 906, 912, 918, 924, 930, 936, 942, 948, 954, 960, 966, 972, 978, 984, 990, 996]
map(function, iterable, ...)
We can take filtering one step further and apply a function to all items in our iterable. Say we want to multiply all numbers by 4 in a list of the first 10 integers.
def times_4(n):
return n*4
We would use map
like this:
>>> list(map(times_4, range(1,10)))
[4, 8, 12, 16, 20, 24, 28, 32, 36]
While the examples here are all on numbers (and many of these functions exist elsewhere in libraries fully optimized for numeric manipulation like math
, pandas
and numpy
), these built-ins can equally transfer to text and other data. Imagine, for instance, pluralizing words that end in “er” pulled from a large file of words, for which filter
and map
would be a perfect dynamic duo.
any()
and all()
boolean functions
Every once in a while you might need to quickly determine the boolean values of items in a list. Suppose we wanted to determine if any of the numbers in a list were perfect squares. Combining map()
with a function that evaluates whether a number is a perfect square, any()
will quickly and easily do this. Writing the function is_perfect_number()
:
def is_perfect_square(n):
import math
return math.sqrt(n) == int(math.sqrt(n))
>>> is_perfect_square(25)
True
>>> is_perfect_square(26)
False
Now using any()
, let’s see if there are perfect squares betwewn 65 and 80 (we know there aren’t):
>>> any(map(is_perfect_square, range(65,81)))
False
But if we include 81 (by extending our range to 112)
>>> any(map(is_perfect_square, range(65,112)))
True
we arrive at the answer we’d expect, since 81 is a perfect square. What if we wanted to know of all of them were? all()
will do just that.
>>> all(map(is_perfect_square, [4,16,25,36,49]))
True
>>> all(map(is_perfect_square, [4,16,25,36,48]))
False
These two built-ins are very valuable and often neglected — don’t rewrite them and don’t forget when they might come in handy!
zip()
for list threading
We finally come to a built-in that’s been with Python for a long time, zip()
. zip()
is one of those built-ins that you will know when you need to use it. zip()
takes 2 or more iterables as inputs and combines them as a pairwise iterable of tuples. I like to call it “weaving” or “threading” (not to be confused with or related to task “threading”) because each list is woven with another. Explore the examples below:
>>> i1 = ['a', 'b', 'c']
>>> i2 = [1, 2, 3]
>>> list(zip(i1, i2))
[('a', 1), ('b', 2), ('c', 3)]
>>> list(zip(i2, i2))
[(1, 1), (2, 2), (3, 3)]
>>> list(zip(i2, i1))
[(1, 'a'), (2, 'b'), (3, 'c')]
>>> list(zip(i2, i1, i1))
[(1, 'a', 'a'), (2, 'b', 'b'), (3, 'c', 'c')]
… and help()
when you’ve had enough (and need more)
If you’ve ever wanted to avoid looking up information about a method without going back to the web, give help([object])
a shot. Basically, if …
the argument is a string, then the string is looked up as the name of a module, function, class, method, keyword, or documentation topic, and a help page is printed on the console. If the argument is any other kind of object, a help page on the object is generated.
This, of course, only works in interactive sessions (notebooks, console, etc.) but it is tremendously useful!
Now that you know …
Now that you know about bit more about Python built-ins, check out the entire list … cozy up and get familiar with some of the more interesting cast and crew (eval()
, exec()
, dir()
, bin()
, byte()
and hex()
come to mind).
Once this list gets too familiar, upgrade your knowledge and take a look at the very, very useful iterrools
library which is optimized and designed specifically for efficient looping … and don’t forget to use import
!
If you want to see a few more examples, check out the Jupyter Notebook I’ve put together with sample code.