2
By the end of this chapter, you will be able to:
This lesson introduces the data types available to us. We look at integers, strings, lists, and Booleans.
In the previous chapter, we learned about variables and looked at a few of the values/types of data that can be assigned to them. Specifically, we dealt with data of the string and integer types. In this chapter, we will look at the other data types that Python supports. Data types classify data, to tell the interpreter how the program intends to utilize that data. Data types define the different operations that can be performed on the data, how the data is stored, and the meaning of the data.
Let's begin with numerical data types.
Integers
Integers, as we saw in the previous chapter, are numerical data types that are comprised of whole numbers. Whole numbers can be either negative or positive. In the following example, we will see how Python represents integers, and then, we can check their types:
>>> integer = 49
>>> negative_integer = -35
>>> print(type(integer), integer)
<class 'int'> 49
>>> print(type(negative_integer), negative_integer)
<class 'int'> -35
>>>
Additionally, Python integers have unlimited precision. This means that there are no limits to how large they can be (save for the amount of available memory):
>>> large_integer = 34567898327463893216847532149022563647754227885439016662145553364327889985421
>>> print(large_integer)
34567898327463893216847532149022563647754227885439016662145553364327889985421
>>>
Floating Point Numbers
Another numerical type supported by Python is floating point numbers. The type for this kind of value is float. As we saw in the previous chapter, these are represented in the following way:
>>> n = 3.3333
>>> print(n)
3.3333
>>> import math
>>> print(type(math.pi), math.pi)
<class 'float'>, 3.141592653589793
>>> print(type(math.e), math.e)
<class 'float'>, 2.718281828459045
>>>
Here, we import math, which is a built-in Python library that provides access to different mathematical functions and constants. We print out the type and the values of the constants Pi (math.pi) and Euler's number (math.e). The displayed values are approximated.
Furthermore, you can convert an integer to a floating point value by using the float function:
>>> float(23)
23.0
>>>
Binary, Hexadecimal, and Octal Numbers
Binary, hexadecimal, and octal numbers are alternative number systems, as opposed to the common decimal number system that we're accustomed to. Binary numbers are numbers expressed in the base 2 system, which uses only 0s and 1s to represent numbers.
To write binary numbers in Python, write the number and prefix it with 0b. Typing a binary number on the interactive shell outputs its decimal equivalent:
>>> 0b111
7
>>> 0b10
2
>>> 0b1000
8
>>>
Hexadecimal numbers are numbers that are expressed in the base 16 system. The symbols 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, and f are used to represent hexadecimal numbers. Hexadecimal numbers should be prefixed with 0x. Typing a hexadecimal number in the interpreter outputs its decimal equivalent:
>>> 0xf
15
>>> 0x9ac
2476
>>> 0xaf
175
>>>
Finally, we have octal numbers, which are numbers written in the base 8 numbering system. This system uses the digits from 0 to 7 to represent numbers. In Python, they should be prefixed with 0o. Typing an octal number in the interpreter outputs its decimal equivalent:
>>> 0o20
16
>>> 0o200
128
>>> 0o113
75
>>>
To convert any decimal (base 10) number to binary, hexadecimal, or octal numbers, you can use the built-in bin, hex, and oct Python functions, respectively, as shown here:
>>> bin(7)
'0b111'
>>> hex(700)
'0x2bc'
>>> oct(70)
'0o106'
>>>
In this exercise, we'll practice converting between different types of number systems. We will create a script that takes the user's input and converts it into a binary number.
The steps are as follows:
number = input("Convert to binary: ")
# convert number to integer
integer = int(number)
# convert integer to binary
binary = bin(integer)
print(binary)
Besides these types, Python also has support for complex numbers, which comes in handy for scientific calculations that require them, such as Fourier transforms, among others. Python offers several different numeric types and provides a straightforward, intuitive process for converting between them.
In this section, we will discuss the different operators that Python makes available to us.
Arithmetic Operators
Arithmetic operators are mathematical functions that take numerical values and perform calculations on them.
Numerical data types are only as valuable as the operations that you can carry out on them. All of the Python numeric types support the following operations:
We will be demonstrating by using decimal numbers, but these operators can work on operands of any numeric type. As you've already seen, you can add numbers, as follows:
>>> 5 + 8 + 7
20
>>>
You can also carry out subtraction:
>>> 20 - 5
15
>>>
And, you can also perform multiplication:
>>> 4 * 3
12
>>>
Finally, you can perform division:
>>> 12 / 3
4.0
>>>
The division of two numbers, regardless of their value types in Python, will always yield a floating point number.
Floor division is different from classic division, in that it always yields a whole integer. It is a division of two numbers, but the value yielded has any fractional parts discarded. Floor division is also referred to as integer division:
>>> 13 // 2 # classic division would yield 6.5
6
>>>
The modulo operation finds the remainder after the division of one number by another:
>>> 5 % 2
1
>>> 20 % 3
2
>>>
Finally, we have the exponentiation operation, which raises a number to a specified power:
>>> 5 ** 3
125
>>> 10 ** 4
10000
>>>
The difference between this method of exponentiation and using the pow function is that the pow function allows you to pass in a third argument, a divisor, which can be used to find the remainder after dividing the result (the exponentiated value) and the divisor.
Assignment Operators
Aside from the = simple assignment operator, Python has other assignment operators. These are shorthand variations of simple operators, in that they not only do an arithmetic operation but also reassign the variable. The following table lists all of the assignment operators:
The following is an example of these operators in action. x is initially assigned to 10. We add 1 and then reassign x to the result of that operation, 11:
>>> x = 10
>>> x += 1
>>> print(x)
11
>>>
The preceding code is equivalent to the following:
>>> x = 10
>>> x = x + 1
>>> print(x)
11
>>>
The same principle is applicable for all of the operators that are listed in the preceding table.
You can perform all arithmetic operations in Python. All operators can be applied to all numeric types. Python also provides assignment operators as a shorthand way of performing an operation and assignment in one statement.
The order of operations is the collection of rules about which procedures should be evaluated first when evaluating an expression.
In Python, the order in which operators are evaluated is just as it is mathematically: PEMDAS.
Parentheses have the highest precedence. Expressions inside parenthesis are evaluated first:
>>> (9 + 2) * 2
22
>>>
Next, the exponentiation operator is given the second highest precedence:
>>> 2 ** 3 + 2
10
>>>
Multiplication and division (including floor division and the modulo operation) have the same precedence. Addition and subtraction come next:
>>> 8 * 3 + 1
25
>>> 24 / 6 - 2
2
>>> 7 + 5 - 3
9
In cases where two operators have the same precedence (for example, addition and subtraction), statements are evaluated left to right:
>>> 7 - 5 + 4
6
>>> 10 / 5 * 3
6.0
The exception to the preceding rule is with exponents, which are evaluated from the right-most value. In the following example, the evaluation is equivalent to 2^(3^2):
>>> 2**3**2
512
Let's go over what we have learned in this section before moving ahead:
In this activity, we will try to get conversant with the order of arithmetic operators in Python. Rewrite the following equation as a Python expression and get the result of the equation:
Python follows the mathematical rules that you're accustomed to. A lot of what you'd expect to work mathematically can be intuitively tried out in Python, and will often work.
Solution for this activity can be found at page 279.
Write a script that takes user input as days and converts the days into years, weeks, and days, and then prints them out. We can ignore leap years. The aim of this activity is to use different arithmetic operators to split days into years, weeks, and days.
The steps are as follows:
Solution for this activity can be found at page 279.
In this section, we will look at strings in detail.
As we mentioned in the previous chapter, strings are a sequence of characters. The characters in a string can be enclosed in either single (') or double (") quotes. This does not make a difference. A string enclosed in single quotes is completely identical to one enclosed in double quotes:
>>> "a string"
'a string'
>>> 'foobar'
'foobar'
>>>
A double-quoted string can contain single quotes:
>>> "Susan's"
"Susan's"
>>>
A single-quoted string can also contain double quotes:
>>> '"Help!", he exclaimed.'
'"Help!", he exclaimed.'
>>>
You can also build a multiline string by enclosing the characters in triple quotes (''' or """):
>>> s = """A multiline
string"""
>>> print(s)
A multiline
string
>>> s2 = '''Also a
multiline string
'''
>>> print(s2)
Also a
multiline string
>>>
Also, as you saw in the first chapter, you can use the * operator to repeat strings:
>>> print('Alibaba and the', 'thieves ' * 40)
Alibaba and the thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves thieves
>>>
And, you can use the + operator to concatenate strings:
>>> "I " + "love " + "Python"
'I love Python'
>>>
Concatenation will join the two strings just as they are, and will not add spaces; thus, we add a space at the end for each string that forms a word in the preceding example.
Python strings are immutable. This means that once they are assigned to a variable, their value cannot be changed. Consider the following:
>>> string = "flip flop"
>>> string * 8 # a spider wearing slippers
'flip flop flip flop flip flop flip flop flip flop flip flop flip flop flip flop '
Once we print the original value, we will see that the string's original value remains unchanged:
>>> print(string)
flip flop
The same is applicable for all string operations; they do not change any part of
the string:
>>> hello = "Hello "
>>> world = "World"
>>> hello + world
'Hello World'
>>> hello
'Hello '
To change the preceding string, we'd have to reassign the variable to the new string:
>>> hello = hello + world
>>> hello
'Hello World'
Python strings can be indexed. Like most languages, the first character in the sequence in the string is at the index 0.
Consider the string Python is fun. The following is a table showing the index of each character in the string. Characters in the string are indexed in two ways - left to right, which starts at 0, and right to left, which starts at -1:
To get a character from a string, you can use the standard [] syntax:
>>> s = "Python is fun"
>>> s[0]
'P'
>>> print(s[7], s[8])
i s
>>> s[-1]
'n'
>>> s[-13]
'P'
If we try to get a character from an index that doesn't exist, Python will raise an IndexError. Here, we are trying to get a character in an index that's larger than the size of the string itself:
>>> s = "foobar"
>>> s[100]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
>>>
Additionally, you can access characters within a range of indices in a string and get a slice/substring of that string. Slicing syntax is in the following format: string[start_index : end_index].
Note that the returned substring doesn't include the character at the end index, but instead, every character up to it:
>>> string = "championships"
>>> string[0:5]
'champ'
>>> string[5:9]
'ions'
>>> string[-5:-1]
'ship'
Python allows you to omit the start or end index when slicing a string:
>>> string = "foobar"
>>> string[3:]
'bar'
>>> string[:3]
'foo'
Here, we can see that when we pass just the start index while slicing, Python automatically slices the string up to the last index. If we pass only the end index, it slices every character, from the start of the string up to that end index.
Given the following statements, predict what the output will be:
>>> "Living in a silent film"[5]
>>> "[8, 9, 10]"[4]
>>> "Don't try to frighten us with your sorcerer's ways"[13:19]
>>> "Testing 1, 2, 3"[7:]
>>> "A man, a plan, a canal: Panama."[:-1]
Solution for this activity can be found at page 280.
The length of a string is determined by the number of characters there are inside of it. In Python, you can get the length of a string by using the built-in len() function, which takes a string as its parameter and returns an integer. In the following example, we can see that the length of the string is 44 characters:
>>> question = "Who was the first Beatle to leave the group?"
>>> len(question)
44
>>>
An empty string would have a length of 0:
>>> empty = ""
>>> len(empty)
0
>>>
String formatting is important when you want to build new strings that are using existing values. Python provides several ways to format text strings. The most popular of these are string interpolation, the str.format() method, and % formatting.
String Interpolation
In Python 3.6, support for string interpolation was added. String interpolation is the process of evaluating a string that has placeholders. These placeholders can hold expressions that yield a value, which is then placed inside the string. Special kinds of strings, known as f-strings (formatted strings), are used during string interpolation. These strings are prefixed with an f to denote how they're meant to be interpreted:
>>> pie = 3.14
>>> f"I ate some {pie} and it was yummy!"
'I ate some 3.14 and it was yummy!'
>>>
If you omit the f prefix, the string will be interpreted literally, as-is.
To insert the variable, we need to place curly braces that contain the expression we want to put inside the string. This can be any valid Python expression:
>>> number = 7
>>> f"{number+1} is just a number."
'8 is just a number.'
>>>
Python string interpolation provides powerful, declarative, and more intuitive formatting of your strings, compared to the other methods that Python offers. This should be the de facto way to format strings when using Python 3.6+.
To read more on string interpolation, visit https://www.python.org/dev/peps/pep-0498/.
The str.format() Method
The format() method can be found on every string instance. It allows you to insert different values in positions within the string. This method works similarly to interpolation, save for the fact that you can't put expressions into the placeholders, and you have to pass in the values for insertion in the method call. The syntax for this is as follows:
>>> fruit = "bananas"
>>> "I love {}".format(fruit)
'I love bananas'
>>>
In the preceding string, we put curly braces in the positions where we want to put our values. When we call the format method, it takes that first argument (our variable, fruit), and replaces the curly braces with its value. You can also pass multiple values in.
The values can be any kind of object:
>>> age = 40
>>> years = 10
>>> string = "In {} years, I'll be {}"
>>> string.format(years, age)
"In 10 years I'll be 40"
>>>
If the Python version you're using doesn't support string interpolation, this should be the method that you use.
% Formatting
An old, deprecated way of formatting strings, which you might end up seeing in old code, is the C language style % formatting. In this method, you use the % operator to pass in values. Inside the string, you use the % character, followed by a format specifier, to declare how the value should be inserted; for example, %s for string, or %d for integers:
>>> number = 3
>>> pets = "cats"
>>> "They have %d %s" % (number, pets)
'They have 3 cats'
This method is inflexible and is harder to use correctly, and thus, it should generally be avoided.
Aside from the format method, string instances have a couple of useful methods that can be used to transform and inspect strings. We will demonstrate a few of the common ones. You can read through the Python documentation for more information on string methods.
str.capitalize()
The str.capitalize() method returns a copy of the string with the first letter capitalized and the rest in lowercase:
>>> "HELLO".capitalize()
'Hello'
>>> "hello".capitalize()
'Hello'
str.lower()
The str.lower() method returns a copy of the string with all characters converted to lowercase:
>>> "WORLD".lower()
'world'
>>> "wOrLd".lower()
'world'
str.upper()
The str.upper() method returns a copy of the string with all characters converted to uppercase:
>>> "abcd".upper()
'ABCD'
>>> "EfGhi".upper()
'EFGHI'
>>>
str.startswith()
The str.startswith() method checks whether a string starts with the specified prefix. The prefix can contain one or more characters, and is case-sensitive. The method returns a Boolean, True or False:
>>> "Python".startswith("Py")
True
>>>
str.endswith()
The str.endswith() method is just like the startswith method, but it checks that the string ends with the specified suffix:
>>> "Python".endswith("on")
True
>>>
str.strip()
The str.strip() method returns a copy of the string with the leading and trailing characters removed. The method also takes an argument that is a string, specifying the set of characters to be removed. This method is also case-sensitive. If no arguments are passed to it, it removes all of the trailing and leading whitespaces.
This can be useful when sanitizing data:
>>> "Championship".strip("ship")
'Champion'
>>> "repair".strip("r")
'epai'
>>> " John Doe ".strip()
'John Doe'
>>>
str.replace()
The str.replace() method takes two substrings as arguments (old and new), then returns a copy of the string with all of the occurrences of the old substring replaced with the new one. Note that the method is case-sensitive:
>>> "Cashewnuts".replace("Cashew", "Coco")
'Coconuts'
>>> "Emacs".replace("Emacs", "Vim")
"Vim"
>>>
There are a lot more string methods available for use. You can read through the Python documentation for more information on string methods at https://docs.python.org/3/library/stdtypes.html#str.
You don't have to remember all of the string methods off the top of your head, as you can always refer to the documentation to see what methods strings support. To do this in the interpreter, run the following command:
>>> help(str)
You should see the following output, which you can browse through:
Write a script that converts the last n letters of a given string to uppercase. The script should take the string to convert and an integer, specifying the last n letters to convert as input from the user. You can assume that n will be a positive number.
The steps are as follows:
The output should look something like this:
Solution for this activity can be found at page 280.
Reviewing what we have learned about strings, we should remember that the characters in a string are indexed, and you can access characters in each index. Python string indices start at 0. You can also access characters within a range of indices by slicing the string. Of the different string formatting methods that Python allows for, you should use string interpolation when using Python versions 3.6+, and the str.format() method otherwise.
An escape sequence is a sequence of characters that does not represent its literal meaning when inside of a string. An escape character tells the interpreter/compiler to interpret the next character(s) in a special way and ignore its usual meaning, thus creating an escape sequence.
In Python, the escape character is the backslash (). For example, adding inside a string will tell the interpreter to interpret a new line inside the string, instead of the literal letter n:
>>> print("Hello World")
Hello
World
>>>
You can escape quotes inside a string, so that they are not interpreted as closing quotes:
>>> 'Weekend at Bernie's'
File "<stdin>", line 1
'Weekend at Bernie's'
^
SyntaxError: invalid syntax
>>> 'Weekend at Bernie's'
"Weekend at Bernie's"
>>>
Here is the full list of valid escape sequences in Python:
In this exercise, we will write a Python script that breaks down all the words of a sentence and prints each word on its own line, and will ring a bell when it's done. The goal of this exercise is to get familiar with escape sequences:
sentence = input("Sentence: ")
sentence = sentence.replace(" ", " ")
print(sentence, "a")
Escape sequences in strings tell the program to perform a function or command, such as inserting a new line, ignore quotes occurring in strings, prompting the terminal to emit an audible signal, and several other functions.
Let's review what we have learned about strings:
Write a script that counts and displays the number of occurrences of a specified word in a given excerpt. The script should request two input values from the user, that is, the excerpt and the word to search for. You can assume that the word will not occur as a substring in other words.
The steps are as follows:
The output should look like this:
Solution for this activity can be found at page 281.
This is part one of two regarding lists, which we will be going through in this book. This part will act as an introduction, and will not cover the various methods that list objects have, such as extend(), remove(), pop(), and several others. We will go through the second section on lists in a later chapter.
In Python, arrays (or the closest abstraction of them) are known as lists. Lists are an aggregate data type, meaning that they are composed of other data types. Lists are similar to strings, in that the values inside them are indexed, and they have a length property and a count of the objects inside of them. In Python, lists are heterogeneous, in that they can hold values of different types. In contrast to how arrays are in most languages, Python lists are also mutable, meaning that you can change the values inside of them, adding and removing items on the go.
Lists can be likened to a wardrobe. Wardrobes can hold multiple items of clothing, clothes of different kinds, and even shoes. Wardrobes provide a convenient storage space for the easy retrieval of your clothes, and make it so that you don't have to look for them all around the house. If we didn't have a list, we'd have to keep track of dozens of separate variables. Like wardrobes, lists provide a convenient collection of related objects.
Lists are made with is comma-separated elements enclosed in square brackets; for example:
>>> digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
>>> digits
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
>>> letters = ["a", "b", "c", "d"]
>>> letters
['a', 'b', 'c', 'd']
>>> mixed_list = [1, 3.14159, "Spring", "Summer", [1, 2, 3, 4]]
>>> mixed_list
[1, 3.14159, 'Spring', 'Summer', [1, 2, 3, 4]]
>>>
As you can see here, lists can also contain other lists within them. You can also get the number of elements in a list by using the len() function:
>>> len(["a", "b", "c", "d"])
4
>>>
Indexing
Like strings, lists can also be indexed. The first element in a list starts at the index 0:
>>> fruits = ["apples", "bananas", "strawberries", "mangoes", "pears"]
>>> fruits[3]
'mangoes'
Negative indices can be used, as well:
>>> fruits[-1]
'pears'
>>>
Slicing
Lists can also be sliced. The slicing operation always returns a new list that's been derived from the old list. The syntax remains as list[start_index : end_index ]. As with string slicing, the element at the end index isn't included in the result:
>>> my_list = [10, 20, 30, 40, 50, 60, 70]
>>> my_list[4:5]
[50]
>>> my_list[5:]
[60, 70]
>>>
Omitting the end index and providing only the start index will slice everything from the start to the end of the list, while omitting the start index and giving only the end index will slice everything from the start index to the end index:
>>> my_list = [10, 20, 30, 40, 50, 60, 70]
>>> my_list[5:]
[60, 70]
>>> my_list[:4]
[10, 20, 30, 40]
>>>
Concatenation
Additionally, you can add two lists together by using the + operator. The elements of all of the lists being concatenated are brought together inside one list:
>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
>>> ["a", "b", "c"] + [1, 2.0, 3]
['a', 'b', 'c', 1, 2.0, 3]
>>>
Changing Values in a List
Since lists are mutable, you can change the value in a list by assigning whatever is at that index:
>>> names = ["Eva", "Keziah", "John", "Diana"]
>>> names[2] = "Jean"
>>> names
['Eva', Keziah, 'Jean', 'Diana']
>>>
Note that it's possible to add any type of value to a list, regardless of what types of values it contains. For example, you can add an integer to a list of strings or a string to a list of integers, and so on.
You can also use the list.append() method to insert a value at the end of a list:
>>> planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
>>> planets.append("Planet X")
>>> planets
['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune', 'Planet X']
Finally, you can assign slices of a list. This replaces the target slice with whatever you assign, regardless of the initial size of the list:
>>> alphanumeric_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
>>> alphanumeric_list[4:7]
[5, 6, 7]
>>> alphanumeric_list[4:7] = ["a", "b", "c"]
>>> alphanumeric_list
[1, 2, 3, 4, 'a', 'b', 'c', 8, 9, 0]
An important thing to note is that when you assign a list, it points it to an object in the memory. If you assign another variable to the variable that references that list, the new variable also references that same list object in the memory. Any changes made using either reference will always change the same list object in the memory.
In this exercise, we will see how list references work:
>>> list_1 = [1, 2, 3]
>>> list_2 = list_1
>>> list_2.append(4)
>>> list_1
[1, 2, 3, 4]
>>> list_1[0] = "a"
>>> list_2
['a', 2, 3, 4]
>>>
This is because both variables reference the same object.
We will be covering lists in further depth in Chapter 5, Lists and Tuples.
We've seen that lists are collections of values. Python lists are mutable. There are multiple operations that you can carry out on lists, such as accessing elements by index, slicing elements, getting the count of elements inside a list, concatenation, and changing values, either by index, appending, or replacing slices of the list.
Write a program that fetches the first n elements of a list.
The steps are as follows:
The output should look like this:
Solution for this activity can be found at page 282.
Boolean data types are values that can only be one of two values, True or False. For example, the proposition 100 is more than 5 is True, and thus, it would have a True Boolean value. On the other hand, the proposition The sky is green is False, and thus, it would have a False Boolean value.
Booleans are largely associated with control statements, as they change the flow of the program, depending on the truthfulness of the specified quantities.
In Python, True and False are used to represent the two Boolean constants:
>>> True
True
>>> False
False
>>> print(type(True), type(False))
<class 'bool'> <class 'bool'>
We can see that the type of each expression is bool (short for Boolean). Like all other types, Booleans have operators that you can apply.
Comparison operators compare the values of objects or the objects, identities themselves. The objects don't need to be of the same type. There are eight comparison operators in Python:
The following are some example uses:
>>> 10 < 1
False
>>> len("open") <= 4
True
>>> 10 > 1
True
>>> len(["banana"]) >= 0
True
>>> "Foobar" == "Foobar"
True
>>> "Foobar" != "Foobar"
False
>>>
Now, consider the following code:
>>> l = [1, 2, 3]
>>> l2 = l
>>> l is l2
True
>>> l is not None
True
>>>
Here, we create a list, l, and then assign the variable l2 to that same list. This creates a reference for the list. Thus, the statement l is l2 is True, since both variables reference the same object in the memory.
The statement l is not None evaluates to True, as well, since l points to something in the memory, and therefore, it isn't null. None is the Python equivalent of null.
We use logic in everyday life. Consider the following statements:
Each of these statements has a condition. The condition for having water is if there isn't any juice available. The chef will only use the knife if two conditions are met, that is, that it is sharpened and that it is polished. The condition for staying awake is only if the condition of being tired has not been met.
In the same way, we have logical operators that combine Boolean expressions in Python: not, and, and or, as described in the following table:
and is a short-circuit operator, in that it only evaluates the second argument if the first one is True. or is also a short-circuit operator, in that it will only evaluate the second argument if the first one is False.
The following is an example of and:
>>> fruits = ["banana", "mangoes", "apples"]
>>> wants_fruits = True
>>> len(fruits) > 0 and wants_fruits
True
>>>
The following code shows or in action:
>>> value_1 = 5
>>> value_2 = 0
>>> value_1 > 0 or value_2 > 0
True
>>>
Finally, the following is an example of not:
>>> not True
False
>>> not False
True
>>>
The operators in and not in test for membership. All sequences (for example, lists and strings), support this operator. For lists, these operators go through each element to see whether the element being searched for is within the list. For strings, the operators check whether the substring can be found within the string. The return values for these operators are True or False.
Let's see how they work:
>>> numbers = [1, 2, 3, 4, 5]
>>> 3 in numbers
True
>>> 100 in numbers
False
>>> sentence = "I like beef, mutton and pork"
>>> "chicken" not in sentence
True
>>> "beef" not in sentence
False
>>>
Boolean data types are values that can be either True or False. You can compare the values of two objects by using comparison operators, and you can combine or alter Boolean expressions by using logical operators. Membership operators are used to assert whether an element can be found in a sequence or container type object.
Insert the appropriate Boolean operators in the following condition statements, so that the code in the block executes. This will help us practice using Boolean operators:
n = 124
if n % 2 ? 0:
print("Even")
age = 25
if age ? 18:
print("Here is your legal pass.")
letter = "b"
if letter ? ["a", "e", "i", "o", "u"]:
print(f"'{letter}' is not a vowel.")
In this chapter, we took an in-depth look at the basic data types that Python supports. We started with numerical data types and their related operators. We then covered strings and looked at string indexing, slicing, and formatting. Then, we moved on and took a brief look at lists (also known as arrays) and Booleans, as well as Boolean operators.
In the next chapter, we will begin our journey into learning how to control the flow of our programs by using control statements and loops.