Types
Python has a set of basic types that most larger programs are built from. If you ever browse through any library or program someone has built, you'll most likely see one of these types used.
Boolean
# Type
bool
# Values
True
False
Booleans are simply whether a value is true or not. They're as simple as they get. Also, before I get too far ahead of myself, I used a special Python syntax for my comments. the # Type
and # Values
are what's known as comments. They signify that everything after the #
is a comment from the programmer to other programmers, and that it should be ignored. I'll go over this more later.
Numbers
Integer
# Type
int
# Values
-100
-3
0
1
9999
Integers are positive or negative whole numbers (not decimals. We will get to them shortly). Like any numbers, we can do math with them. Python has a set of basic arithmetic that we can use for any number type.
# Addition
1 + 2
# Returns 3
# Subtraction
4 - 2
# Returns 2
# Multiplication
3 * 10
# Returns 30
# Division
1 / 2
# Returns 0
# Modulus (Remainder)
3 % 4
# Returns 3
# Exponents
10**3
# Returns 1000
# Brackets also work too!
(1 + 2) * 3
# Returns 9
# And what happens when we divide by zero?
1 / 0
# Raises ZeroDivisionError
Let's break this down a bit. The addition, subtraction, multiplication, modulus, exponents, and brackets are very self explanatory, but what's happening with the division? Integers are only whole numbers, so it will always round down when a decimal number will be produced. There are a couple of ways around this that I will introduce later on. Also, the ZeroDivisionError is something special that will be handled in the Exceptions chapter.
Python also supports testing if integers are greater than, less than, equal to, or not equal to another number.
# Greater than
1 > 2
# Returns False
# Less than
3 < 10
# Returns True
# Greater than or equal to
3 >= 10
# Returns False
# Less than or equal to
10 <= 10
# Returns True
# Not equal to
10 != 10
# Returns False
# Equal to
3 == 3
# Returns True
Long Integers
# Type
long
# Values
3L
100000000000L
Longs are very special integers. In Python 2, there's a maximum value for Integers. On my system, it is 9223372036854775807
. Once I go over this value, Python will automatically switch to using longs instead. Long values theoretically do not have a maximum value, but practically it is whatever the computer can store in memory.
Floats (Decimals)
# Type
float
# Values
1.0
0.0
-1.0
1.23456789
1e10
1e-10
inf
nan
Floats are approximations of decimal numbers. This means that there are certain values that floats do not support. Unless you are working with financial data, this will probably never be an issue. However, one thing to note is that the further the value is away from 0.0
, the less accurate the number will be. This problem can be seen in Maya when an object is over a million units away from the origin, and then animated. The animation will likely be choppy when the object is moved because there is not enough resolution at that distance.
Also, floats support two special values. inf
is infinite, and nan
is not a number. It is most likely that you will not see these values while programming, but knowing about them is always useful. One thing to note is that you cannot directly type in these values in Python. There is a way to get the values, but I will go over that shortly.
Mix and Match
1.0 + 2
# Returns 3.0
1L + 2
# Returns 3L
1.0 / 2
# Returns 0.5
3 / 4.0
# Returns 0.75
1.0 == 1
# Returns True
3 < 0.123
# Returns False
1L != 1.0
# Returns False
All numbers support math operations and value testing using any other number, regardless of type. One thing to note, is the type of the number can change depending on the types that are used. For example, doing an operation with an int
and a long
will return a long
, while doing an operation with an int
or long
with a float
will return a float
.
None
# Type
NoneType
# Value
None
None
is a very special type. It represents nothing. While 0 can represent nothing, 0 is not nothing, since it has a type (int
). Also, unlike other types, you cannot cast something to None
(will explain casting later). Also, Python does not expose NoneType
by default. This is very useful for specifying default arguments in functions, or as a value to initialize a variable to when searching for specific objects.
Casting
int(1.0)
# Returns 1
float(123)
# Returns 123.0
long(1.23456)
# Returns 1L
# What happens if we use a float that would usually be rounded up?
int(1.5)
# Returns 1
# What happens if we don't add a value?
float()
# Returns 0.0
Python lets you convert from one type to another by using the syntax <type>(<value>). Also, you can get the default value of the type by leaving out the value when "calling" the type.
Mutable vs Immutable
Before we move onto the other basic types, I should mention the concept of mutable vs immutable objects. Mutable means that the value can be changed, while immutable means that the value cannot be changed unless the value is completely reassigned. I will go into more examples with the next types. All of the shown types are immutable. This will mean more when we go further in the tutorial.
String
# Type
str
unicode
# Values
# Single line strings
"Hi! My name is Scott!"
"Isn't Python awesome?"
"a"
'Here is another string using different quotes.'
'These let me "mix and match".'
"I can also \"escape\" quotes using a backslash."
"12345"
# Multi-line strings
"""One line of test not enough?
Use 3 quotes!"""
'''Single quotes work just fine too.
Cool, eh?'''
u"We also support unicode characters"
Strings store text. They're immutable like the number types, but they are different for a few reasons. One of them is that strings are sequences of characters. For example, the string "This is a string"
is represented in memory like T
h
i
s
i
s
a
s
t
r
i
n
g
. Each character is given an index starting with 0. The reason why it starts with 0 is that it represents the offset from the start of the block of memory. So, 0 means that the character has no offset from the start, and 1 is 1 character away from the start of the memory block, and so on.
Another way to represent this idea is like this:
| T | h | i | s | | i | s | | a | | s | t | r | i | n | g |
| -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
It is possible to access specific characters from a string since strings are sequences. The way it is done is through querying the index. String queries support forwards and backwards querying, and querying a subset of characters.
# What is the first character?
"This is a string"[0]
# Returns 'T'
# What is the second character?
"This is a string"[1]
# Returns 'h'
# What is the last character?
"This is a string"[-1]
# Returns 'g'
# What is the second to last character?
"This is a string"[-2]
# Returns 'n'
# What are all of the characters after the fifth character?
"This is a string"[5:]
# Returns 'is a string'
# What are all of the characters before the sixth character?
"This is a string"[:5]
# Returns 'This '
# What are all of the characters between the fourth and tenth characters?
"This is a string"[3:9]
# Returns 's is a'
# What if we want to skip every second character?
"This is a string"[::2]
# Returns 'Ti sasrn'
# How about reversing the string?
"This is a string"[::-1]
# Returns 'gnirts a si sihT'
We can get the length, or the number of characters of the string using len
.
len("This is a string")
# Returns 16
Strings can be joined together by using +
, or can expand a single character or multiple characters using *
.
"Hi, my name is " + "Scott Wilson."
# Returns "Hi, my name is Scott Wilson."
# Note that the first string ends with a space.
"My favourite number is " + str(42) + "."
# Returns "My favourite number is 42."
# Only strings can be joined with other strings. The 42 has to be converted to a
# string by casting it to a string with the str().
"a" * 3
# Returns "aaa"
"abc" * 3
# Returns "abcabcabc"
If there are a lot of strings to join together, the faster way is using the join
method of the string.
" ".join("This", "is", "a", "string.")
# Returns "This is a string."
", ".join("spam", "spam", "bacon", "spam")
# returns "spam, spam, bacon, spam"
Strings can also support substituting contents of the string using string formatting. There are two ways to do it. One is using the C way of string formatting, and the other is using the string's format method.
# C style string formatting.
"My name is %s %s." % ("Scott", "Wilson")
# Returns "My name is Scott Wilson."
"My favourite number is %d." % 42
# Returns "My favourite number is 42."
"My name is %(first)s %(last)s." % {"first": "Scott", "last": "Wilson"}
# Returns "My name is Scott Wilson."
# String format method.
"My name is {0} {1}.".format("Scott", "Wilson")
# Returns "My name is Scott Wilson."
# Note that the 0 and 1 represent the index of the arguments in the format
# method. Another way to write the line is:
"My name is {1} {0}.".format("Wilson", "Scott")
# And the result will be exactly the same.
"My name is {} {}.".format("Scott", "Wilson")
# Returns "My name is Scott Wilson."
# Note that this way assumes that the order of arguments is the order of
# placeholders.
"My name is {first} {last}.".format(first="Scott", last="Wilson")
# Returns "My name is Scott Wilson."
However, strings cannot have their letters changed once the string is initialized, or created. This is due to the fact that strings are immutable. The string will have to be recreated with the changed character.
"This is a string"[8] = "b"
# Raises TypeError: 'str' object does not support item assignment
Lastly, strings also support comparisons ==
, !=
, >
, <
, >=
, and <=
. This is based off of the length of the string, and the characters in the string. For example, "b"
is greater than "a"
because "b"
comes after "a"
in the alphabet. Strings also support checking if strings are inside other strings.
"Scott" in "Scott Wilson"
# Returns True
"Scott" in "Python"
# Returns False
"Python" not in "The plane"
# Returns True
"abcdefg".startswith("abc")
# Returns True
"abcdefg".endswith("efg")
# Returns True
Lists
# Type
list
# Values
[1, 2, 3, 4, 5]
["Spam", "Spam", "Bacon", "Spam"]
[42, "Python"]
[[1, 2, 3, 4, 5], ["Spam", "Spam", "Bacon", "Spam"], True, 1.0, [42, "Python"]]
Lists are mutable
types that can accept any type in Python. Including lists of lists (of lists of lists...). They are ordered in the order of how the items were added to the list. For example, adding "a", "b", and "c" in that order will result in the list ["a", "b", "c"]
. However, adding "c", "b", "a" will result in the list ["c", "b", "a"]
.
There are four ways to add items to a list.
append
adds an item to the end of the list.
insert
adds an item to the list at a certain position.
extend
will join one list to another.
+
will join one list to another, like extend
.
# I assign the list to a variable for the sake of demonstration. Variables will
# be explained in more detail later.
my_list = []
my_other_list = ["Spam", "Spam", "Bacon", "Spam"]
my_list.append("apples")
# Result: ["apples"]
my_list.insert(0, "bananas")
# Result: ["bananas", "apples"]
my_list.insert(1, "bread")
# Result: ["bananas", "bread", "apples"]
my_list.extend([1, 2, 3, 4, 5])
# Result: ["bananas", "bread", "apples", 1, 2, 3, 4, 5]
my_list + my_other_list
# Returns ["bananas", "bread", "apples", 1, 2, 3, 4, 5, "Spam", "Spam", "Bacon", "Spam"]
# Note that the + doesn't edit the list in place.
It is possible to remove items from a list too.
pop
removes and returns an item at an index.
remove
removes the first occurrence of an item.
del
will delete an item at an index.
# We will continue using the my_list variable. As a quick reminder, the list
# looks like this:
# ["bananas", "bread", "apples", 1, 2, 3, 4, 5]
my_list.pop(0)
# Returns "bananas"
# Result: ["bread", "apples", 1, 2, 3, 4, 5]
my_list.pop(999)
# Raises IndexError. There aren't 1000 items in the list.
my_list.remove("bread")
# Result ["apples", 1, 2, 3, 4, 5]
my_list.remove("cheese")
# Raises ValueError. We never added cheese to the list.
del my_list[0]
# Result [1, 2, 3, 4, 5]
del my_list[999]
# Raises IndexError. There aren't 1000 items in the list.
Adding and removing items from a list is fine. But, lists are most useful when getting items from a list. Luckily we already know the syntax for that. It is exactly the same as strings.
# Resetting my_list to be like how it was before items were deleted.
my_list = ["bananas", "bread", "apples", 1, 2, 3, 4, 5]
my_list[0]
# Returns "bananas"
my_list[0:2]
# Returns ["bananas", "bread", "apples"]
my_list.index("apples")
# Returns 2
# Note that index will return the index of the first item it sees that matches,
# Or raise a ValueError.
Sometimes, lists needs to be sorted. There are two ways to do that. sorted
and sort
. sorted
will return a new sorted list, while sort
will sort the list in place.
my_list = [3, 1, 4, 5, 2]
sorted(my_list)
# Returns [1, 2, 3, 4, 5]
my_list.sort()
# Result: [1, 2, 3, 4, 5]
There may be times when the list will need to be updated. The list can be easily updated because it is mutable
.
my_list = ["bananas", "bread", "apples"]
my_list[0] = "cheese"
# Result: ["cheese", "bread", "apples"]