**This tutorial on Python Built in Data Types explains various data types including None and Numeric in Python along with examples:**

As a newbie, one of the first data types we usually learn is **string**, **number,** and **boolean**. However, these are not often sufficient to represent more specialized data objects.

In this modern age, more complex applications are emerging, with data as the backbone. So representing data in the most efficient way is the key.

**=> Check ALL Python Tutorials Here**

What You Will Learn:

## Python Built In Data Types

In Python and most programming languages, data types are considered as a representation, collection, or categorization of data.

In Python, data can be categorized into: **numeric**, **sequence**, and **mapping**. Of course, we can’t forget the **None** object which denotes an empty value, typically represented with **Null** in JavaScript. Most often, **numeric** and **None** are considered **scalar types**.

**Given below is a table of the various data types in None and Numeric.**

**Table 1**: Data types and their categories in Python

Category | Sub-category | Data Type | Description |
---|---|---|---|

Scalar | None | None | This is an empty object |

Numeric | int | These are whole numbers(positive and negative) e.g. 3, 55, -2, 0 | |

float | These are floating-point numbers(positive and negative) e.g. 3.2, 4e2, -4.0 | ||

complex | These are positive and negative numbers with real and imaginary components specified as |
||

bool | This is either True or False representing yes or no, 1 or 0 respectively. |

### None Type

**None** is an immutable object that represents an empty value. Other programming languages, such as JavaScript, C++, etc , use **null** instead.

The None object can be used in many ways. One of the ways is to initialize a variable that will be assigned a value later in the program. This helps us to verify the variable’s value and take appropriate decisions.

**Example 1**:

KEY = None # Initialize variable # Check variable and take decision if KEY is None: # condition holds print("Key hasn't been set yet") else: print("Key has been set") # set the variable KEY = '3848774939' # check variable and take decision if KEY is None: print("Key hasn't been set yet") else: # condition holds print("Key has been set")

**Output:**

By default, it is returned by other objects that don’t explicitly return a value. We can bet that when we started learning Python, we didn’t know about this, mainly because the Python interpreter doesn’t print this default **None** returned by objects unless explicitly asked to do so.

**Example 2**: Define a function that explicitly doesn’t return a value

def test(): print("This function returns nothing") if __name__ == '__main__': test() # returns None but not printed print(test()) # returns None and printed.

**Output:**

We see from above that the first call to **test()** printed a text on the console. But mind you, this is not a returned value. The function actually returned a **None** object but the interpreter didn’t print it. This is because all objects by default return this **None** object, so printing them each time will be inconvenient.

We had to explicitly instruct the interpreter to print it by using the **print()** function as seen above.

**Note**: All Python functions that seem to return nothing, actually return the **None** object type. Even object’s methods that modify their objects in-place do return the **None** type. Let’s take a look at the list’s method **sort()**.

**Example 3**: Investigate the return type of the list** sort()** method.

>>> myList = [4,2,8,1] # define a list >>> result = myList.sort() # sort the list in-place and assign the return value >>> myList # check the sorted list [1, 2, 4, 8] >>> print(result) # print the returned value None

### Numeric Type

As seen in the **Table 1** above, Numeric or Number types in Python include **integers**, **floating-point numbers**, **complex** numbers and **Boolean**(subtype of integers). In Python, they are defined as int, float, complex and bool class respectively.

As we shall see throughout this section, **numeric literals**, **built-in functions** and **operators** generate **Numbers**. **Integers** are generated by** integer literals** including **hex**, **octal** and **binary** **numbers**. **Floating point numbers** are generated by numeric literals having a decimal point or an exponent sign.

**Complex numbers** are generated by numeric literals with ‘**j**‘ or ‘**J**‘(imaginary part) appended to it and an optional integer or float that represents the real part.

**Let’s dwelve a bit deep into each of these numeric types.**

#### Integers

Integers are signed whole numbers of unlimited range. Meaning, the size of the number represented is only limited by the available memory.

**It is important to note two things:**

- Python
**2.x**had both signed and long integers. However, the latter was dropped in Python**3.x** - Unsigned integers don’t exist in Python
**3.x**.

**The table below shows some integer constants and their interpretation.**

**Table 2**: Integer constants and their interpretation

Integer Constant | Interpretation |
---|---|

4553, 0, 2, -343, -1 | Signed Integers |

0o1, 0o2, 0o62 | Octal |

0x1, 0x2, 0x32 | Hexadecimal |

0b1, 0b10, 0b110010 | Binary |

From the **Table 2** above, we see **Octal**, **Hexadecimal,** and **Binary**. These may confuse us as to why are these considered integers. Well, the **Decimal number** system or** base 10** numbers are the commonly used numbers for our day-to-day work.

However, our computers actually work with **binary**(**base 2**), **hexadecimal**(**base 16**), and **octal** (**base 8**) number systems behind the scene.

As seen in the **Table 3** below, they are represented with prefixes.

**Table 3**: Non-based 10 representations

Number System | Abbreviation | Base | Prefix | Description |
---|---|---|---|---|

Binary | bin | 2 | ‘0b’ or ‘0B’ | (zero + lowercase letter ‘b’) OR (zero + uppercase letter ‘B’) |

Hexadecimal | hex | 16 | ‘0x’ or ‘0X’ | (zero + lowercase letter ‘x’) OR (zero + uppercase letter ‘X’) |

Octal | oct | 8 | ‘0o’ or ‘0O’ | (zero + lowercase letter ‘o’) OR (zero + uppercase letter ‘O’) |

**Example 4**: To better understand that these are integers, let’s compare their types to that of a decimal(base 10) number.

>>> type(50) # decimal <class 'int'> >>> type(0o62) # oct <class 'int'> >>> type(0x32) # hex <class 'int'> >>> type(0B110010) # bin <class 'int'>

We see that they are all of type ‘**int**’.

Python has built-in functions that are used to convert from decimal to **hex**, **bin** and **oct**. Check the example below.

**Example 5**: Convert decimal number **50** to **hex**, **oct** and **bin**.

>>> hex(50) '0x32' >>> oct(50) '0o62' >>> bin(50) '0b110010'

### Floating Point Number

Floating point numbers or **floats** are represented as** 64-bits** double precision numbers. **Floats** have the data type **float**.

From the example in** Table 1**, we can deduce that floating point numbers can be represented in two ways using:

- Decimal point (
**.**) - Scientific notation ‘
**e**‘ or ‘**E**‘ followed by a signed integer where the notation basically stands for the power of 10.

**Example 6**: Ways to represent floating point numbers.

>>> a = 45.32 # decimal point >>> a 45.32 >>> type(a) <class 'float'> >>> b = 34e-3 # scientific notation >>> b 0.034 >>> type(b) <class 'float'>

Unlike integers, floats have limits. The highest represented number of floats is about **1.7 * 10^308** or as exponential notation, **1.8e308** and the lowest represented number of **2.2e-308.**

These can be derived from the system sys.float_info named tuple using its **min** and **max** attribute. This named tuple holds low-level information about the precision and internal representation of the float type.

Any number beyond this range will be considered **infinite**. Meaning, the number is beyond the allowed floating point value on your machine. **Infinity** in Python is also of type **float** and is named **inf**. We also have negative **infinity**, i.e any floating point number below the minimum limit of about 2.2e-308

**Example 7**: Check Python floating point limits

>>> f = 1.8e308 # define a float above the max limit >>> f inf >>> type(f) # check data type of infinity <class 'float'> >>> nf = -1.8e308 # define a float below the min limit >>> nf -inf >>> type(nf) # check data type of negative infinity <class 'float'>

### The Float() Function

Python built-in** float()** is a function that returns a floating-point number. It takes in an optional input and returns its floating-point representation. If the input is a string, it should be **Numeric** else a **ValueError** will be raised.

**Example 8**: Derive floating-point numbers from strings with** float()** function

>>> s1 = '4' >>> s2 = '45.99' >>> s3 = '-05' >>> s4 = '2a' # not numeric >>> print(type(s1), type(s2), type(s3), type(s4)) # check all types <class 'str'> <class 'str'> <class 'str'> <class 'str'> >>> float(s1) 4.0 >>> float(s2) 45.99 >>> float('-03') -3.0 >>> float(s4) # error, s4 is not numeric Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: could not convert string to float: '2a'

### Special Numbers

In Python, we have various special numbers that turn out to be floats: +/**-infinity**(inf), **nan**. In the section above, we saw infinite and learned what they represent. We also have the **nan**, commonly known as “Not a Number” but as ironic as it may seem, **nan** is a floating point number.

In **example 7**, we saw how we could obtain the infinity float. Mind you that with the** float()** function, we can generate these special numbers as well.

**Example 9:** Generating the special numbers with the **float() **function.

>>> x = float('nan') # 'NaN', 'Nan', 'naN', 'nAn' will work. >>> x nan >>> x == float('nan') # are not equivalent False >>> x == x # not equivalent to itself False >>> x is float('nan') # are not identical False >>> x is x # is identical to itself True >>> float('infinity') # or '-infinity' inf >>> float('inf') inf >>> float('-inf') -inf

As seen above, another strange behavior of **nan** is that they are not equivalent.

**NB**: The difference between the two operators **==** and **is** is that, the former checks for equality of values while the latter checks for identity of object. We will see more on these operators later.

### Complex Number Type

If we did calculus math in high school, then we should already know about complex numbers. Mostly popular in the domain of scientific computing and computer graphics, Python supports them under the hood.

**Syntax**

n + mj

Where **n** and **m** are any numbers(signed integers, floating point numbers). The **n** represents the real part and **m** the imaginary part, with the letter **j** at the end.

**Example 10**: Define a complex number with real value of **4** and imaginary value of **10**.

>>> a = 4 + 10j >>> a (4+10j) >>> type(a) # check type <class 'complex'> >>> a.real # get real part 4.0 >>> a.imag # get imaginary part 10.0

We can see that the output is enclosed in braces. This is to make sure that the different parts that make up the complex number are tight together and not confused to an expression.

As seen above, this data type comes with two properties, **real** and **imag** which returns the real and imaginary values(floats) respectively.

We will end this section by looking at some basic mathematical operations that can be performed on complex numbers.

**Example 11**: Mathematical operations on complex numbers.

>>> a = 3 + 5j >>> b = 1 + 10j >>> a + b # addition (4+15j) >>> a - b # subtraction (2-5j) >>> a * b # multiplication (-47+35j) >>> a ** b # raise to the power (0.0001919555598433972-3.639489680921175e-05j) >>> a / b # division (0.5247524752475248-0.24752475247524752j) >>> a.conjugate() # conjugate (3-5j) >>> a // b # floor division Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't take floor of complex number.

We can notice that complex numbers don’t support the **floor division operator**(**//**). Also, we can get the opposite sign(imaginary part) of a complex number by using its **conjugate()** method.

### Boolean Type

In Python, boolean type is a built-in data type that represents the truthy and falsy evaluation of an expression like 39 > 9(**True**) and 0 < -1(**False**).

As seen from the expressions above, we notice two possible values that make up the boolean type:

- True
- False

**Example 12**: Check the type of **True** and **False**.

>>> type(False) <class 'bool'> >>> type(True) <class 'bool'>

Just as integer numbers belong to a class **int** and floating-point numbers to a class **float**, boolean belong to a class **bool**.

**About False and True**

**True** and **False** are the only possible boolean types. They belong to the class **‘bool’** which is a built-in data type like **int**, **float**, **list**, etc. However, we should understand these about **True** and **False**

#### Are Keywords

**True** and **False** are keywords in Python with the added advantage that they can be used anywhere an expression is valid.

Like all Python keywords, **False** and **True** can’t be assigned a value. A **SyntaxError** exception is raised if that happens.

**Example 13**: Assign value to a boolean type

>>> False = 0 File "<stdin>", line 1 SyntaxError: can't assign to keyword

#### Are Numbers

We saw in the **Table 1** above as how boolean was classified under **Numeric Type**. This is because **True** and **False** are actually mapped and equivalent to **1** and **0**.

**Example 14**: Check the equivalence of **True** and **False** with **1** and **0**.

>>> True == 1 # is equal to 1 True >>> False == 0 # is equal to 0 True >>> True + True # same as 1 + 1 2 >>> True + False # same as 1 + 0 1 >>> False + False # same as 0 + 0 0 >>> True - True # same as 1 - 1 0

We may ask ourselves how useful **example 14** is. Well, think about the string **count()** method which returns the number of times a substring occurs in a string.

**Example 15**:

def substring_freq(s, substr): return s.count(substr) def substring_freq_2(s, substr): l = [substr ==i for i in s] # compare each item to the substring 'a' print(l) # display the resulting boolean values b = [0 + 1 for i in l] # represent boolean as 0 and 1 print(b) # return sum(l) # sum all boolean values if __name__ == '__main__': s = 'aaebde' substr = 'a' print("Using count()") print(substring_freq(s, substr)) print("Using boolean") print(substring_freq_2(s, substr))

**Output:**

### Boolean Operators

Boolean operators can be considered as operators that compare one or more boolean inputs and return a boolean result. However, this is not the case always. We shall later see that the inputs and results are not always of type boolean.

**The various boolean operators of built-in Python are:**

- OR
- AND
- NOT

Let’s take a closer look at each of them. But before we do that, let’s note that the boolean operators(**OR** and **AND**) use the short-circuit evaluation technique.

Short-circuit evaluation is a principle that determines if the right operand should be evaluated based on the value of the first operand.

#### OR

The output of the **OR** operator is only **True** if at least one of the two inputs is **True**. Let’s see how it works in the truth table below.

**Table 4**: OR operator truth table

X | Y | X OR Y |
---|---|---|

True | True | True |

True | False | True |

False | True | True |

False | False | False |

From the table above, we see that **OR** evaluates to **False** unless either the input is **True**. Let’s break this down and see how it can be used in a program.

Imagine we will like to run an operation only when a condition is **False**. **For example,** if the **mark** is not greater than **10**, print the text “**Try Again!**“.

For this example, we take the advantage of the short-circuit nature of the **OR** operator.

Short-circuit in **OR** operator works this way. If the first operand evaluates to **True**, then the overall result will be **True** and the second operand won’t be evaluated. This is because in this case, the second operand becomes irrelevant since it’s value won’t have any effect on the overall result.

**Example 16**:

>>> mark = 6 >>> mark > 10 or print("Try Again!") # first operands's condition is False Try Again! >>> mark = 12 >>> mark > 10 or print("Try Again!") # first operand's condition is True. True

**NB**: The operands in the example above are not boolean types but the first operand evaluates to a boolean type while the second operand returns a falsy value(**None**). We already saw above that functions or methods that don’t explicitly return a value, by default return **None**.

#### AND

The output of the **AND** operator is only **True** if both the inputs are **True**. Let’s see how it works in the truth table below.

**Table 5**: OR operator truth table

X | Y | X AND Y |
---|---|---|

True | True | True |

True | False | False |

False | True | False |

False | False | False |

Unlike the **OR** operator we earlier met, the **AND** operator is commonly used to run an operation if a condition is **True**.

**For example,** say we want to print “**Bravo**” if the **mark** is greater than **10**.

Just as the **OR** operator, this takes the advantage of the short-circuit evaluation technique.

Short-circuit in **AND** operator works this way; If the first operand evaluates to **False**, then the overall result will be **False** and the second operand won’t be evaluated. This is because in this case, the second operand becomes irrelevant since it’s value won’t have any effect on the overall result.

**Example 17:**

>>> mark = 3 >>> mark > 10 and print("Bravo") # first operand's condition is False. False >>> mark = 12 >>> mark > 10 and print("Bravo") # first operand's condition is True. Bravo

#### NOT

The **NOT** operator takes only one operand and its output is the reverse of its input. If **True**, then the output is **False** and vice versa.

**Table 6**: NOT operator truth table

**Let’s see how it works in the truth table below.**

X | NOT X |
---|---|

True | False |

False | True |

This operator is commonly used to run an operation when a condition is falsy, instead of first checking if the condition is **False** using the equality operator**(==).**

Unlike the **OR** and **AND** operators, this operator takes only one operand and doesn’t support short-circuit evaluation. Hence, always evaluate its operand.

**Example 18:**

def compare(a, b): # function returns True if a is greater than b and False otherwise. return a > b x = 10 y = 9 # using equality operator if compare(y, x) == False: print("False using 'equality operator'") # using NOT operator if not compare(y, x): print("False using 'NOT operator")

**Output:**

### Comparison Operators

Python has built in an awful plenty of operators that are used for comparison. What they do is that they compare a relationship between operands and return a boolean type. These operators can be grouped into various categories.

- Value comparison
**[<, >, ==, >=, <=**, and**!=**] - Membership test operators
**[ in**,**not in**] - Identity comparisons [
**is**,**is not**]

In this section, we won’t try to dive deep into these comparison operators because this is not a tutorial on this subject. We will just see how these operators are related to the boolean type.

#### #1) Value Comparison

These operators can be further divided into:

- Equality
**(==)** - Inequality
**(!=)** - Order
**(<,****>,****=<,****=>)**

They are all used to compare the values of two objects and not their types. We shall later see the operator group that compares types.

**Example 19**: Comparison of object’s values

# equality >>> {'a':3, 'b':2} == {'b':2,'a':3} True >>> [3,4] == [4,3] False # inequality >>> 2 != 4 True >>> [3, 5] != [5, 3] True >>> 2 != 2.0 False # Order >>> 2 > 1 # 2 is greater than 1 True >>> 1 < 1 # 1 is not greater than 1 False >>> 1 <= 1 # 1 is lesser or equal to 1 True >>> 2 >= 3 # 2 is not greater or equal to 3 False

For the first line of code, the order of the dictionary items is different but unlike the list in the second line of code, the equality is **True**. This is because dictionaries are unordered. Meaning their order doesn’t matter as they are accessed using their keys.

#### #2) Membership Test Operators

This group defines two operators, **in** and **not in**. In simple english, membership means being a member of a group. So, **x in s** returns **True** if **x** is a member of **s**, and **False** otherwise. On the other hand, **x not in s** returns the reverse truth value of **x in s**.

**Example 20:** Membership of objects

>>> 4 in [3,5,6,2] # 4 is not a member of the list elements False >>> 4 in [3,5,6,2, 4] True >>> "the" in "the time is now" # "the" is a member as it is a subset. True

#### #3) Identity Comparison

This group defines two operators, **is** and **not is**. The** is operator** compares two object’s identity. That is, for **x is y**, it returns **True** only if **x** and **y** are the same object or they reference the same memory address. The **not is **operator returns the reverse truth value of the** is **operator.

The built-in **id()** function can be used to obtain the identity of an object. The **is** operator is commonly used when comparing to **None**, **True** and **False**.

Though the Equality and Inequality operators can be used here, they are not ideal since they can be tricked to return something different with the special methods **__eq__** and **__ne__** respectively.

**Example 21**:

>>> x = [3,4] >>> y = [3,4] >>> x is y # reference different memory addresses False >>> z = x # 'z' references same memory address as 'x' >>> z is x True >>> x = None # 'x' references the same memory address as None. >>> x is None True

## Frequently Asked Questions

**Q #1) What are the 4 built-in numeric data types in Python?**

**Answer:**

**In Python, the 4 built-in numeric data types are:**

**int**: These are whole numbers of unlimited range.**For example, 23, -47, 884747****long:**These are long integers in Python**2.x**but deprecated in Python**3.x. For example,****43L****float:**These are floating point numbers represented as 64-bits double precision numbers. For example**3.4, 0.0, -2.0****complex:**Are unsigned numbers with real and imaginary components.**For example****3j, 2 – 4j, -22 – 4j**

**Q #2) Why do we use None in Python?**

**Answer: **In Python, **None** is of the data type class **NoneType** and it is used to represent an empty variable. There is a difference between an undefined variable and an empty variable. So, if we want the variable defined but empty, then **None** is the right object to use.

**Q #3) Is NULL function in Python?**

**Answer:** Unlike other languages like JavaScript, PHP, there is no **null** object in Python. Instead, **None** is used to represent an empty variable.

**Q #4) What does bool() do in Python?**

**Answer: **The **bool() **function takes in an argument and returns a boolean value. **False** is returned If the argument is a falsy value, and **True** if argument is a truthy value.

**Some of Python falsy values are:**

- Empty sequences
**( [], (), {}, set(), “”, range(0))** - Zero numeric types
**( 0, 0.0, 0j)** - Some constants
**(None, False)**

**Some of Python truthy values are:**

- None-empty sequences
- Non-zero numeric types
- Some constants
**(True)**

## Conclusion

In this tutorial, we looked at what **data types** are in Python. We explored a bit deeper by looking at two of these data types i.e. **None** and **Numeric**.

We saw that Numeric data types contain the following; **integers**, **floats**, **boolean** and **complex numbers**. For the boolean type, we had a bird’s eye view of the different boolean and comparison operators.

**=> Visit Here To Learn Python From Scratch**