Skip to main content

Section 4.14 None

None, or the NoneType, is a type which represents the absence of a value. But let’s take a step back and think: why is this useful?
In Python, sometimes we don’t want to return anything from a function. However, when we don’t explicitly return anything from a function, Python will implicitly return None.
For the purposes of this class, you should just understand when None appears and why.
Most commonly when students are learning about strings and lists, us educators see a similar issue, which links back to sections on mutability. Strings are immutable and lists are mutable, remember?
When we want to modify a string, we must reassign it, because it’s immutable:
my_string = 'Hello, world!'
new_string = my_string[0:5]
print(new_string)
Your natural instinct may be to write the same thing with lists:
my_list = []
my_list = my_list.append(0)
print(my_list[0])
By doing so, you will incur this error:
print(my_list[0])
~~~~~~~^^^
TypeError: 'NoneType' object is not subscriptable
Frustratingly, your code actually did exactly what you told it to. List functions modify the list directly, because lists are mutable. Therefore, their functions (such as .append(element)) don’t return anything.
But now we know why: append is actually implicitly returning None. This means that in the previous example, we reassigned my_list to None, and then we tried to list access element 0 of None, which caused the ’not subscriptable’ error, because None isn’t a list and can’t have list access done to it.
The solution is simple: don’t reassign the list when calling list functions.
my_list = []
my_list.append(0)
print(my_list[0])
If you remember nothing else, remember: strings get reassigned, lists don’t. This is because strings are immutable; lists are mutable and most of their functions don’t return anything (meaning they implicitly return None!).

Note 4.14.1.

You may be wondering how to tell the difference between functions that return something or not. Sometimes the name of the method can be a hint (e.g. if it has "set" in the name, it probably won’t return, whereas "get" will). If that doesn’t help or you’re still curious, you should reference the documentation (whether it’s official Python documentation or for a library). No shame in looking it up!
You won’t be tested on the information below, but read on for some interesting thoughts on this.
If you’ve been around any other programming languages, you may have heard of equivalent ideas like null, NULL, nullptr, nil, and more. This is such a universal concept in programming and is hugely frustrating to many programmers as it often represents something that went wrong.
Fun (or depressing) fact -- the inventor of null actually regrets his invention:
I call it my billion-dollar mistake... At that time, I was designing the first comprehensive type system for references in an object-oriented language. My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.
- Tony Hoare
Despite this, None, null, and nil don’t seem to be going anywhere anytime soon. :)
You have attempted of activities on this page.