Lesson 08: Data Types or Objects in Python: Part 2

Python represents each “Data Type” by a class; So each data is a sample or object of a specific class. Although the programmer can also define the class of his choice, in this lesson we want to talk about that part of the data types or object types (Object Types) that are provided (Built-in) to the Python interpreter. Is to talk.

This lesson follows some of the other Python types, such as List, Tupel, Dictionary, and Collection.

 
✔ Level: Introductory

Headlines

Lesson 08: Data Types or Objects in Python: Part 2

the list tuple dictionary Collection NoneType Grouping

the list

The “List” type is the most flexible ready-made type in Python. This type is like a “sequence” like a string, but unlike it is a “mutable” type. The list object is created using parentheses [] and can have members – of any type – separated by commas; The list type is actually a place to store various objects:

>>> L = [1, 2, 3]
>>> type(L)
<class 'list'>
>>> L
[1, 2, 3]
>>> print(L)
[1, 2, 3]
>>> import sys
>>> sys.getsizeof(L)
88
>>> L = [] # An empty list
>>> L
[]

List members can be of any type; Even a list:

>>> L = [15, 3.14, 'string', [1, 2]]

The list object is a type of Python sequence and can be accessed by members based on their position index:

>>> L = [1, 2, 3]
>>> L[0]
1
>>> L[-1]
3

Also obtained the number of members of each list object by the len () function [Python Documents]:

>>> L1 = []
>>> len(L1)
0
>>> L2 = ['python', 12.06]
>>> len(L2)
2
>>> len(L2[0])
6
>>> L3 = ['a', [1, 2], 'b']
>>> len(L3)
3
>>> len(L3[1])
2

If a sequence is a member of the object list, using the pattern seq [i] [j], its members can also be obtained, where i is an index that points to a member of the object list, and j also refers to the internal index of member i has it; This pattern can continue in the following way:

>>> L = ['python', 2.56]
>>> L[0]
'python'
>>> L[0][:2]
'py'
>>> L = ['python', 2.56, [128, ['a', 'z']]]
>>> L[2][1][0]
'a'

A common example of a list object is a simulation of a matrix structure:

>>> L = [[1, 2, 3],
... [4, 5, 6],
... [7, 8, 9]]
>>>
>>> L
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> L[0][1]
2

The list object is one of the mutable types of Python and its members can be changed; This change can take the form of deleting, inserting a new member, or replacing one or more members. Python has many practical methods for manipulating and changing the list object, which we will discuss in the following, but in this section we want to examine how to make a change using the assignment operator:

  • Replace:
>>> L = [1, 2, 3]
>>> L[1] = 'py'
>>> L
[1, 'py', 3]
>>> L = [1, 2, 3, 4, 5, 6]
>>> L[:2] = [0, 0]
>>> L
[0, 0, 3, 4, 5, 6]
  • Inserting – i in the pattern seq [i: i] refers to the position of the object seq where we want to insert it; In this way, note that the object you want to insert in the list must be a sequence:
>>> L = [0, 1, 5, 6]
>>> L[2:2] = [2, 3, 4]
>>> L
[0, 1, 2, 3, 4, 5, 6]
>>> L[0:0] = 'abc'
>>> L
['a', 'b', 'c', 0, 1, 2, 3, 4, 5, 6]
>>> L[3:3] = ['d', [-2, -1]]
>>> L
['a', 'b', 'c', 'd', [-2, -1], 0, 1, 2, 3, 4, 5, 6]
  • Delete – Simply assign an empty list object ([]) to one or more members of the list object:
>>> L = [0, 1, 2, 3, 4, 5, 6]
>>> L[2:5] = []
>>> L
[0, 1, 5, 6]

Command del You can also delete a member or a piece of the list object using the del [Python Documents] command:

>>> L = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> del L[2]
>>> L
['a', 'b', 'd', 'e', 'f', 'g']
>>> del L[1:4]
>>> L
['a', 'f', 'g']

We can also use this command to delete a variable completely. By targeting a variable, its reference to the object is also deleted, and if there is no other reference to that object, the object to which the variable was referenced is also deleted:

>>> a = 5
>>> a
5
>>> del a
>>> a
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined

Multiple assignments A list object – or a whole sequence object – can be assigned to a number of names and separate variables can be created; This is called unpacking. In this case, the Python interpreter assigns each member of the sequence to one of the letters in order, which normally should be equal to the number of letters in the sequence:

>>> L = [1.1, 2.2, 3.3, 4.4]
>>> a, b, c, d = L
>>> a
1.1
>>> b
2.2
>>> c
3.3
>>> d
4.4
>>> a, b = [1.1, 2.2, 3.3, 4.4]
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)

But one of the letters can be marked with a * symbol; In this case, the Python interpreter creates a balance between the sequence members and the letters, in which case all the extra members – in the form of a list object – are assigned to the marked name. Of course, it should be noted that the order of the sequence members will be observed in all circumstances; Note the sample codes below:

>>> L = [1.1, 2.2, 3.3, 4.4]
>>> a, b, *c = L
>>> a
1.1
>>> b
2.2
>>> c
[3.3, 4.4]
>>> *a, b = [1.1, 2.2, 3.3, 4.4]
>>> a
[1.1, 2.2, 3.3]
>>> b
4.4
>>> a, *b, c = [1.1, 2.2, 3.3, 4.4]
>>> a
1.1
>>> b
[2.2, 3.3]
>>> c
4.4
>>> a, b, c, *d = [1.1, 2.2, 3.3, 4.4]
>>> a
1.1
>>> b
2.2
>>> c
3.3
>>> d
[4.4]

Copy As with other objects, another variable of this object type can be created by assigning an existing variable from the list object to a new name. Of course, as stated earlier; In this case, the object is not copied and only a new reference of this new name is given to the variable object. This can be tested using the id () function [Python Documents]; The output of this function is equal to the address of the object in memory, and obviously two identical id values for two variables indicate that their object is the same:

>>> L1 = [1, 2, 3]
>>> L2 = L1
>>> L2
[1, 2, 3]
>>> id(L1)
140254551721800
>>> id(L2)
140254551721800

The members of a list object are variable, and we should note that now that both variables point to the same object, if one of the variables changes the members of the object, our expected value of the object of the second variable will also change:

>>> L1 = [1, 2, 3]
>>> L2 = L1
>>> L1[0] = 7
>>> L1
[7, 2, 3]
>>> L2
[7, 2, 3]

If we consider this a problem, to solve it we can make a copy of the variable object and attribute this copy to the new variable; In this case, both variables will point to separate objects in different locations of memory. Normally no new work is needed to copy a list object and you can use indexing [:] – meaning all members -:

>>> L1
[7, 2, 3]
>>> L2 = L1[:]
>>> L1
[7, 2, 3]
>>> L2
[7, 2, 3]
>>> id(L1)
140254551721928
>>> id(L2)
140254551721800
>>> L1[0] = 5
>>> L1
[5, 2, 3]
>>> L2
[7, 2, 3]

python-list-assignment
python-list-assignment
But if the list object has members of the list type (or any other variable type), the above problem still remains for these members. Note the sample code and image below:

>>> L1 = [1, 2, [7, 8]]
>>> L2 = L1[:]
>>> L2
[1, 2, [7, 8]]
>>> L1[2][1] = 5
>>> L1
[1, 2, [7, 5]]
>>> L2
[1, 2, [7, 5]]
>>> id(L1)
140402644179400
>>> id(L2)
140402651379720
>>> id(L1[2])
140402644179080
>>> id(L2[2])
140402644179080

python-list-assignment-02
python-list-assignment-02
In Python, object copying is done in two ways, “Shallow Copy” and “Deep Copy”, which are accessed by the copy () and deepcopy () functions from within the copy module, respectively [Python Documents]. In the superficial copy method, as I did before – that is, assigning using the index [:] – internal objects are not copied and only a new reference is given to them; While the deep copy method also creates a copy of all internal (variable) objects:

>>> L1 = [1, 2, [7, 8]]
>>> import copy
>>> L2 = copy.copy(L1) # Shallow Copy
>>> L1[2][1] = 5
>>> L1
[1, 2, [7, 5]]
>>> L2
[1, 2, [7, 5]]
>>> L1 = [1, 2, [7, 8]]
>>> import copy
>>> L2 = copy.deepcopy(L1) # Deep Copy
>>> L1[2][1] = 5
>>> L1
[1, 2, [7, 5]]
>>> L2
[1, 2, [7, 8]]
>>> id(L1)
140402651379656
>>> id(L2)
140402644179400
>>> id(L1[2])
140402644106312
>>> id(L2[2])
140402651379080

Operators for lists You can use the + operators (to link lists) and * (to repeat list members):

>>> [1, 2] + [2, 3] + [3, 4]
[1, 2, 2, 3, 3, 4]
>>> ['python'] * 3
['python', 'python', 'python']

To check the equality of the values of the two objects in the list, like other objects, the == operator can be used:

>>> [1, 'python'] == [1, 'python']
True
>>> [1, 'python'] == [1, 'PYTHON']
False

Membership operators can also be used to check for an object in the list:

>>> L = ['a', [1, 2]]
>>> 'b' not in L
True
>>> 2 in L
False
>>> [1, 2] in L
True

Difference between == and is operators

The point that was not made in the previous lessons is to express the difference between the equality operator and the identity operator. Before giving an explanation, pay attention to the sample code below:

>>> a = 5
>>> b = a
>>> a == b
True
>>> a is b
True
>>> L1 = [1, 2, 3]
>>> L2 = L1
>>> L1 == L2
True
>>> L1 is L2
True
>>> L2 = L1[:]
>>> L1 == L2
True
>>> L1 is L2 # False!
False

Lesson 5 We remember that every object in Python contains an “identity”, a “type” and a “value”. The == operator examines two objects for the same “value”, while the is operator examines two objects for identical “identities” (output of the (id) function) or their address in memory.

It has already been stated that the Python interpreter avoids rebuilding existing “correct” objects and small “strings” to save time and memory, and only gives them a new reference. But this is not the case with other objects, and the Python interpreter creates and references a new object for each variable defined for this type of object:

>>> a = 5
>>> b = 5
>>> a == b
True
>>> a is b
True
>>> m = 'python'
>>> n = 'python'
>>> m == n
True
>>> m is n
True
>>> L1 = [1, 2, 3]
>>> L2 = [1, 2, 3]
>>> L1 == L2
True
>>> L1 is L2 # False!
False

Become a list object

Using the list () class [Python Documents], you can create a list object or convert sequential objects to a list object:

>>> a = 'python'
>>> type(a)
<class 'str'>
>>> b = list(a)
>>> type(b)
<class 'list'>
>>> b
['p', 'y', 't', 'h', 'o', 'n']
>>> L = list()
>>> L
[]

Application methods of a list object

The list object is changeable, and its methods, unlike the string object, do not return a new modified object, but make changes to the same object.

  • append (x – adds the x object to the end of the list:
>>> L = [1, 2, 3]
>>> L.append(4)
>>> L
[1, 2, 3, 4]
>>> L.append(['a', 'b'])
>>> L
[1, 2, 3, 4, ['a', 'b']]

The function of this method L. append (x))) is the same as the operation L +[x]:

>>> L = [1, 2, 3]
>>> L + [4]
[1, 2, 3, 4]
  • extend (s) adds the members of the s sequence object to the end of the list:
>>> L = [1, 2, 3]
>>> L.extend(['a', 'b'])
>>> L
[1, 2, 3, 'a', 'b']
>>> L = [1, 2, 3]
>>> L.extend('py')
>>> L
[1, 2, 3, 'p', 'y']
  • insert (i, x) – puts a new member (such as x) in a position on the list with the desired index (such as i):
>>> L = [1, 2, 3]
>>> L.insert(0, 'python')
>>> L
['python', 1, 2, 3]
  • remove (x) – Looks for object x in the list on the left and removes the first item found from the list. If no member equal to object x is found, it reports an error:
>>> L = [1, 2, 3, 5, 2 , 6 , 1]
>>> L.remove(2)
>>> L
[1, 3, 5, 2, 6, 1]
>>> L.remove(0)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list

Attention In cases where you want to remove a specific index from the list; Use the del command.

  • pop ([i]) – delete the corresponding member of the i index from the list and return it as output. If the index is not sent to the method, it will delete and return the last member of the list by default:
>>> L = ['a', 'b', 'c', 'd']
>>> L.pop(2)
'c'
>>> L
['a', 'b', 'd']
>>> L.pop()
'd'
>>> L
['a', 'b']

Attention The [] symbol in the methods template is the only way to express the optionality of the expression inside it and is not part of the method.

  • index (x [, n]) – In the list, look for the object x on the left and return the index of the first item found. This method also has an optional argument (n) that can be used to specify the index of several items. Returns found.If no member equals object x is found it reports an error:
>>> L = ['s', 'b', 'c', 'a', 's', 'b']
>>> L.index('b')
1
>>> L.index('b', 2)
5
>>> L.index('z')
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
ValueError: 'z' is not in list
  • count (x) – Returns the number of occurrences of object x in the list:
>>> L = ['a', 'b', 'c', 'a', 'a', 'b']
>>> L.count('a')
3
>>> L.count(5)
0
  • clear () – deletes all members of the list. The function of this method is equivalent to the [:] del L command:
>>> L = [0, 1, 2, 3, 4, 5]
>>> L.clear()
>>> L
[]
>>> L = [0, 1, 2, 3, 4, 5]
>>> del L[:]
>>> L
[]
  • reverse () – inverts the members of the list:
>>> L = ['a', 'b', 'c', 'd']
>>> L.reverse()
>>> L
['d', 'c', 'b', 'a']
  • sort () – Sorts members of a list:
>>> L = [4, 6, 2, 1, 5, 0, 3]
>>> L.sort()
>>> L
[0, 1, 2, 3, 4, 5, 6]
>>> L = ['g', 'e', 'h', 'f', 'd']
>>> L.sort()
>>> L
['d', 'e', 'f', 'g', 'h']

By default, this method sorts in ascending order, but you can change the descending order by sending a True value to the optional reverse argument:

>>> L = [4, 6, 2, 1, 5, 0, 3]
>>> L.sort(reverse=True)
>>> L
[6, 5, 4, 3, 2, 1, 0]

The sort () method has another optional argument called key, which can be passed to each member of the list before comparing and sorting by sending a single argument function to it. Of course, it should be noted that only the function name should be sent to the method argument and not its complete template; For example, a function with a pattern (func (x) must be passed as key = func. If the key argument is passed, this method sends the list members to the specified function and finally considers their output for sorting. For example, code Note below:

>>> L = ['a', 'D', 'c', 'B', 'e', 'f', 'G', 'h']
>>> L.sort()
>>> L
['B', 'D', 'G', 'a', 'c', 'e', 'f', 'h']

As you can see, the uppercase letters are at the top of the sorted list; In fact, the uppercase letters in the list are evaluated to a smaller value, and if you pay attention to the ASCII code of these letters, you will understand the reason for this evaluation. To solve this problem, we can convert all letters to uppercase or lowercase before the comparison operation is performed by sorting the list members so that the letters are at the same level for comparison:

>>> L = ['a', 'D', 'c', 'B', 'e', 'f', 'G', 'h']
>>> L.sort(key=str.lower)
>>> L
['a', 'B', 'c', 'D', 'e', 'f', 'G', 'h']

What does str.lower mean in the example code above? In the previous lesson, we learned about the str () class, which was used to create a string object, and we also worked on some of its methods that were available for a string object (such as join). In the future, we will learn by the lesson about classes that methods can be called using the class name without creating an object; The same thing happened here, and lower (s) is a single-argument method inside the str class called by the name of this class.

>>> str
<class 'str'>
>>> str.lower
<method 'lower' of 'str' objects>
>>> dir(str)
['__add__', '__class__', '__contains__', '__delattr__',
'__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__getnewargs__',
'__gt__', '__hash__', '__init__', '__iter__', '__le__',
'__len__', '__lt__', '__mod__', '__mul__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__rmod__', '__rmul__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', 'capitalize', 'casefold',
'center', 'count', 'encode', 'endswith', 'expandtabs',
'find', 'format', 'format_map', 'index', 'isalnum',
'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower',
'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper',
'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition',
'replace', 'rfind', 'rindex', 'rjust', 'rpartition',
'rsplit', 'rstrip', 'split', 'splitlines', 'startswith',
'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

tip Using the ready (dir) function [Python Documents] we can get a list of all available attributes and methods of an object.

Instead of the sort () method, you can use the ready sorted () function [Python Documents] with the same explanation:

>>> L = ['a', 'D', 'c', 'B', 'e', 'f', 'G', 'h']
>>> sorted(L)
['B', 'D', 'G', 'a', 'c', 'e', 'f', 'h']
>>> sorted(L, key=str.lower, reverse=True)
['h', 'G', 'f', 'e', 'D', 'c', 'B', 'a']

Create a stack A “stack” is a structure for temporarily storing data in such a way that the last data it contains will be the first data to be output; This is called LIFO or Last In, First Out. The stack only supports two operations (or methods): push, which puts data on top of all the data in it, and pop, which extracts the highest data. Stack structure can be easily implemented using the list type in Python; For a list object, the append () method is equivalent to push and the pop () method is equivalent to pop:

>>> stack = []
>>> stack.append(1)
>>> stack.append(2)
>>> stack.append(3)
>>> stack
[1, 2, 3]
>>> stack.pop()
3
>>> stack.pop()
2
>>> stack
[1]

Tuple

The “Tuple” type is the same as the list type, except that it is not changeable and its members are enclosed in parentheses ():

>>> t = (1, 2, 3)
>>> type(t)
<class 'tuple'>
>>> t
(1, 2, 3)
>>> print(t)
(1, 2, 3)
>>> import sys
>>> sys.getsizeof(t)
72
>>> t = () # An empty tuple
>>> t
()

A comma symbol must be placed at the end of the single-member tuple object; Such as: (, 1). Since parentheses are also used in expressions; This allows the Python interpreter to identify a tuple object from the phrase:

>>> (4 + 1)
5
>>> a = (1)
>>> a
1
>>> type(a)
<class 'int'>
>>> t = (1,)
>>> t
(1,)
>>> type(t)
<class 'tuple'>

To create a tuple object, you can even skip parentheses and separate only objects (or phrases) with commas:

>>> 5,
(5,)
>>> 1, 2 , 'a', 'b'
(1, 2, 'a', 'b')
>>> t = 'p', 'y'
>>> t
('p', 'y')
>>> 5 > 1, True == 0 , 7-2
(True, False, 5)

Attention

Due to its immutability, the tuple type is more efficient than the list type in terms of memory consumption; Therefore, it is better to use this type when there is no need for special changes in the data. Also, when data does not need to be changed, using object tops instead of lists can protect them against change.

Due to the many similarities between the tuple object and the list object, we avoid giving duplicate explanations and mention only a few examples related to the type of tuple:

>>> ('a', 'b', 'c') + (1 , 2, 3)
('a', 'b', 'c', 1, 2, 3)
>>> ('python', 0) * 3
('python', 0, 'python', 0, 'python', 0)
>>> t = ('p', 'y', [1, 2, 3], 5)
>>> 'p' in t
True
>>> 2 not in t
True
>>> [1, 2, 3] not in t
False
>>> (1, 'python') == (1, 'python')
True
>>> (1, 'python') == (1, 'PYTHON')
False
>>> t1 = (1, 2, 3)
>>> t2 = t1
>>> t2 == t1
True
>>> t2 is t1
True
>>> t1 = (1, 2, 3)
>>> t2 = (1, 2, 3)
>>> t2 == t1
True
>>> t2 is t1
False
>>> t = ('p', 'y', [1, 2, 3], 5)
>>> t[0]
'p'
>>> t[-1]
5
>>> t[:2]
('p', 'y')
>>> t[2]
[1, 2, 3]
>>> t[2][1]
2
>>> t[0] = 'j'
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> t = ('p', 'y', [1, 2, 3], 5)
>>> len(t)
4
>>> len(t[2])
3

Due to the reference structure between objects in Python, which was also displayed by the images in the list section; The changeable objects inside the topple object have their own properties and will continue to be changeable:

>>> t = ('p', 'y', [1, 2, 3], 5)
>>> t[2][1] = 8
>>> t
('p', 'y', [1, 8, 3], 5)

See also the example of the following code about Unpacking:

>>> a, *b = (1.1, 2.2, 3.3, 4.4)
>>> a
1.1
>>> b
[2.2, 3.3, 4.4]
>>> a, *b, c = (1.1, 2.2, 3.3, 4.4)
>>> a
1.1
>>> b
[2.2, 3.3]
>>> c
4.4
>>> a, *b = [1.1, 2.2, (3.3, 4.4)]
>>> a
1.1
>>> b
[2.2, (3.3, 4.4)]
>>> a, *b, c = [1.1, 2.2, (3.3, 4.4)]
>>> a
1.1
>>> b
[2.2]
>>> c
(3.3, 4.4)
>>> a, *b, c = (1.1, 2.2, (3.3, 4.4))
>>> a
1.1
>>> b
[2.2]
>>> c
(3.3, 4.4)

You must have noticed that the members of the sequence are assigned only by the type of list named.

When assigning the Tupel variable, pay attention to the issue of not copying changeable objects and use the copy module if necessary:

>>> t1 = ('p', 'y', [1, 2, 3], 5)
>>> t2 = t1 # No Copy
>>> t1[2][1] = 8
>>> t1
('p', 'y', [1, 8, 3], 5)
>>> t2
('p', 'y', [1, 8, 3], 5)
>>> t1 = ('p', 'y', [1, 2, 3], 5)
>>> import copy
>>> t2 = copy.deepcopy(t1) # Deep Copy
>>> t1[2][1] = 8
>>> t1
('p', 'y', [1, 8, 3], 5)
>>> t2
('p', 'y', [1, 2, 3], 5)

Like a list object; The topple object also has access to two methods (index) and count () – this can be checked using the dir () function:

>>> t = ('s', 'b', 'c', 'a', 's', 'b')
>>> dir(t)
['__add__', '__class__', '__contains__', '__delattr__',
'__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__getnewargs__',
'__gt__', '__hash__', '__init__', '__iter__', '__le__',
'__len__', '__lt__', '__mul__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__rmul__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'count', 'index']
>>> t.index('b')
1
>>> t.index('b', 2)
5
>>> t.index('z')
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
ValueError: tuple.index(x): x not in tuple
>>> t.count('a')
3
>>> t.count(5)
0

Have you forgotten to use the guide?!:

>>> t = ('s', 'b', 'c', 'a', 's', 'b')
>>> help(t.index)
Help on built-in function index:
index(...) method of builtins.tuple instance
 T.index(value, [start, [stop]])
-> integer -- return first index of value.
 Raises ValueError if the value is not present.
(END)

Whenever there is a need to make a change in the topple object; The object can be temporarily converted to a list object. In this case, you can use the properties and methods of the list object and apply the desired changes, and finally return to the top object with another type conversion. For this purpose, you can use the list () class to convert a sequence – here a tuple object – to a list object, and on the other hand, you can use a tuple () class to convert a sequence – here a list object – to a tuple object. Appearance:

>>> t = (1, 2, 3)
>>> type(t)
<class 'tuple'>
>>> L = list(t)
>>> type(L)
<class 'list'>
>>> L
[1, 2, 3]
>>> L.insert(0, 'python')
>>> L
['python', 1, 2, 3]
>>> t = tuple(L)
>>> t
('python', 1, 2, 3)

Of course, when you want to sort the members inside a topple object, there is no need to change the list type and you can use the sorted () function; This function takes a topple object as previously introduced and returns a list object with the same but sorted members:

>>> t = ('a', 'D', 'c', 'B', 'e', 'f', 'G', 'h')
>>> sorted(t, key=str.lower, reverse=True)
['h', 'G', 'f', 'e', 'D', 'c', 'B', 'a']

The tuple () class without an argument creates an empty tuple object:

>>> t = tuple()
>>> t
()
>>> type(t)
<class 'tuple'>

dictionary

Another flexible version available in Python is the Dictionary, abbreviated dict. Dictionary objects are represented by parentheses و و and each data is stored in it as a pair of “key: value”. This type of object is also called a Python mapping object because in this type, each “key” object is given to a map “value” object. The dictionary object is not a sequence but is changeable and the “value” of each member is accessed by the corresponding “key”. The “value” object can be of any type, even another dictionary object, but the “key” object should only be selected from the “immutable” types, and it should be noted that all the “keys” of a dictionary object must be “unique”. .

>>> d = {1:'One', 2:'Two', 3:'Three'}
>>> type(d)
<class 'dict'>
>>> d
{1: 'One', 2: 'Two', 3: 'Three'}
>>> print(d)
{1: 'One', 2: 'Two', 3: 'Three'}
>>> import sys
>>> sys.getsizeof(d)
288

In the example code above; Objects 1, 2, and 3 are object keys that are mapped to objects ‘One’, ‘Two’, and ‘Three’, respectively. To access any value of the dic dictionary object, we use the [dic [key] pattern, in which the key is the key attached to the desired value:

>>> d = {1:'One', 2:'Two', 3:'Three'}
>>> d[0]
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 0
>>> d[1]
'One'
>>> d[3][2:]
'ree'

d [3] refers to the value ‘Three’; And since this object is a sequence, we can also access the members of this object in the sequence method (that is, using the position index).

Consider a few more examples:

>>> d = {} # An empty dictionary
>>> d
{}
>>> d = {'name': 'Bob', 'age': 40}
>>> d['name']
'Bob'
>>> d['age']
40
>>> d = {'cb4f2': {'name': 'Bob', 'age': 40}}
>>> d['cb4f2']['age']
40

The structure of the dictionary type is similar to the hash table and has many applications in search algorithms. This type can also be used to organize and store data on file; For example, suppose we want to have a few Benedict Cumberbatch movies so that we can access them based on the year of production:

>>> benedict_cumberbatch = {'2014':'The Imitation Game',
...
'2013':('The Fifth Estate', '12 Years a Slave',
'Star Trek Into Darkness'),
...
'2012':'The Hobbit: An Unexpected Journey',
...
'2011':('War Horse', ' Wreckers',
'Tinker Tailor Soldier Spy')}
>>>
>>> benedict_cumberbatch['2014']
'The Imitation Game'
>>> len(benedict_cumberbatch['2011'])
3
>>> benedict_cumberbatch['2011'][0]
'War Horse'

The len () function can also be used to obtain the number of members of a dictionary object (key pair: value):

>>> d = {1:'One', 2:'Two', 3:'Three'}
>>> len(d)
3

By assigning a new value to an existing key of a dictionary object, the value of that key can be changed, and by assigning a value to a new key that does not exist in the dictionary object, a new member is added to that object:

>>> d = {'name': 'Bob', 'age': 40}
>>> d['name'] = 'Jhon'
>>> d
{'name': 'Jhon', 'age': 40}
>>> d['job'] = 'unemployed'
>>> d
{'name': 'Jhon', 'job': 'unemployed', 'age': 40}

Unlike object lists or topples (or whole sequences), which are ordered data and whose order or location of members is important, a dictionary object is not, and the order of members is completely irrelevant.

Using the same command del dic [key], a member of a dictionary object can also be deleted:

>>> d = {'name': 'Jhon', 'job': 'unemployed', 'age': 40}
>>> del d['job']
>>> d
{'name': 'Jhon', 'age': 40}

It is not possible to change the keys unless you delete the desired member and add a new member (same value but with a new key):

>>> d = {'name': 'Jhon', 'job': 'unemployed', 'age': 40}
>>> d['occupation'] = d['job']
>>> del d['job']
>>> d
{'name': 'Jhon', 'age': 40, 'occupation': 'unemployed'}

Operators for Dictionary

The + and * operators are not defined for dictionary objects.

Membership operators can be used to check for a key in a dictionary object:

>>> 'job' in {'name': 'Bob', 'age': 40}
False
>>> 'job' not in {'name': 'Bob', 'age': 40}
True

The function of the equality operator == and the identity operators (is and is not) are discussed; These operators are also used for dictionary objects.

Copy

As mentioned, the dictionary object is a “variable” type of Python, and the same description was given to the list object; This is also true here and sometimes it is necessary to use the copy module to copy dictionary objects:

  • No copying:
>>> d1 = {'name': 'Bob', 'age': 40}
>>> d2 = d1
>>> d1 == d2
True
>>> d1 is d2
True
>>> d1['age'] = 46
>>> d1
{'name': 'Bob', 'age': 46}
>>> d2
{'name': 'Bob', 'age': 46}
  • Surface copy:
>>> d1 = {'name': 'Bob', 'age': 40}
>>> import copy
>>> d2 = copy.copy(d1) # shallow copy
>>> d1 == d2
True
>>> d1 is d2 # False!
False
>>> d1['age'] = 46
>>> d1
{'name': 'Bob', 'age': 46}
>>> d2
{'name': 'Bob', 'age': 40}
>>> d1 = {'names': ['Bob', 'Jhon'], 'ages': [40, 40]}
>>> import copy
>>> d2 = copy.copy(d1) # shallow copy
>>> d1 == d2
True
>>> d1 is d2 # False!
False
>>> d1['ages'][0] = 46
>>> d1
{'ages': [46, 40], 'names': ['Bob', 'Jhon']}
>>> # d2 has changed!
>>> d2
{'ages': [46, 40], 'names': ['Bob', 'Jhon']}
  • Deep copy:
>>> d1 = {'names': ['Bob', 'Jhon'], 'ages': [40, 40]}
>>> import copy
>>> d2 = copy.deepcopy(d1) # deep copy
>>> d1 == d2
True
>>> d1 is d2 # False!
False
>>> d1['ages'][0] = 46
>>> d1
{'ages': [46, 40], 'names': ['Bob', 'Jhon']}
>>> d2
{'ages': [40, 40], 'names': ['Bob', 'Jhon']}

Become a dictionary object

The dict (Python documentation) class is used to convert other objects to a dictionary type or to create a dictionary object in general. Note that the members of the dictionary object are sent to the class through arguments in the form of “key = value“:

>>> d = dict(one=1, two=2, three=3)
>>> d
{'two': 2, 'one': 1, 'three': 3}
>>> d['one']
1

In this case, to select the keys, we must follow the rules for choosing a name in Python; For example, a key that starts with a number is not allowed.

To send keys and values we can use the zip (Python documents) function and send the output of this function as an argument to the dict class. It can be thought that this function takes a number of sequential objects and puts their peer-to-peer members together; These sequences must have an equal number of members; Because the extra members of each sequence are ignored. The output (zip) is a new zip object and is usually converted to a list type for viewing:

>>> k = [1, 2, 3, 4, 5]
>>> v = ['x', 'y', 'z']
>>> z = zip(k, v)
>>> z
<zip object at 0x7eff1d263548>
>>> type(z)
<class 'zip'>
>>> list(z)
[(1, 'x'), (2, 'y'), (3, 'z')]
>>> k = (1, 2, 3)
>>> v = ('One', 'Two', 'Three')
>>> d = dict(zip(k, v))
>>> d
{1: 'One', 2: 'Two', 3: 'Three'}

In the future we will use the zip () function again.

Some practical methods of a dictionary object

>>> # Python 3.x
>>> d = {1:'One', 2:'Two', 3:'Three'}
>>> d.items()
dict_items([(1, 'One'), (2, 'Two'), (3, 'Three')])
>>> d.values()
dict_values(['One', 'Two', 'Three'])
>>> d.keys()
dict_keys([1, 2, 3])

Note that in 3x Python versions the output of these methods is of a different type that you can see using type (); This type is called dict_view [Python Documents 3x]. These methods do not return a copy of the data (members or values or keys), but can be said to open a window to see what it is, and whenever this data changes, these outputs also change. To better view these outputs, you can convert them to a list type:

>>> list(d.items())
[(1, 'One'), (2, 'Two'), (3, 'Three')]
>>> list(d.values())
['One', 'Two', 'Three']
>>> list(d.keys())
[1, 2, 3]

These methods do not have such output in Python 2x and return only one copy of the data. However, version 2.7 ports equivalent methods to viewitems () (Python Documents), viewvalues (), Python Documents, and viewkeys ():

>>> # Python 2.7
>>> d = {1:'One', 2:'Two', 3:'Three'}
>>> d.viewitems()
dict_items([(1, 'One'), (2, 'Two'), (3, 'Three')])
>>> d.viewvalues()
dict_values(['One', 'Two', 'Three'])
>>> d.viewkeys()
dict_keys([1, 2, 3])
>>> # Python 2.x
>>> d = {1:'One', 2:'Two', 3:'Three'}
>>> d.items()
[(1, 'One'), (2, 'Two'), (3, 'Three')]
>>> d.values()
['One', 'Two', 'Three']
>>> d.keys()
[1, 2, 3]
>>> d = {1:'One', 2:'Two', 3:'Three'}
>>> d.clear()
>>> d
{}
  • copy (Python documents) – This method returns a superficial copy of the object:
>>> d1 = {'name':'Bob'}
>>> d2 = d1.copy()
>>> d1 is d2
False
  • fromkeys (seq) [Python Documents] – Receives a sequence of keys and creates a new dictionary object using them; however, the keys in this object have no value that must be set at another time:
>>> k = (1, 2, 3) # or k=[1, 2, 3] or k='123'
>>> dict.fromkeys(k)
{1: None, 2: None, 3: None}

Note that this method is called by the dict class itself. This method also has an optional argument by which an object can be specified as the default “value” of keys:

>>> k = (1, 2, 3)
>>> dict.fromkeys(k, '-*-')
{1: '-*-', 2: '-*-', 3: '-*-'}
  • pop (key) [Python Documents] – The member holding the key removes the key and returns its value. Reports:
>>> d = {1:'One', 2:'Two', 3:'Three'}
>>> d.pop(2)
'Two'
>>> d
{1: 'One', 3: 'Three'}
>>> d.pop(2)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 2
>>> d.pop(2, 'Oops!')
'Oops!'

This method can be used to change keys more easily !:

>>> d = {'name': 'Jhon', 'job': 'unemployed', 'age': 40}
>>> d['occupation'] = d.pop('job')
>>> d
{'name': 'Jhon', 'age': 40, 'occupation': 'unemployed'}

Another similar method is available called popitem () (unsupported Python documents); This method arbitrarily deletes a member of the object in each call and returns it in the form of a key (value, key), and if the dictionary is empty, it reports a KeyError error:

>>> d = {1:'One', 2:'Two', 3:'Three'}
>>> d.popitem()
(1, 'One')
  • get (key) [Python Documents] – Returns the value of the key. Does not report any errors:
>>> d = {1:'One', 2:'Two', 3:'Three'}
>>> d.get(1)
'One'
>>> d.get(0)
>>>
>>> d.get(0, False)
False
  • setdefault (key) [Python Documents] – Returns the value of the key. If there is no member with this key in the object, it adds the key with the default value (the second argument, which is optional) into the object, and Returns this value itself; if the second argument is not passed, the default value will be None:
>>> d = {1:'One', 2:'Two', 3:'Three'}
>>> d.setdefault(1)
'One'
>>> d
{1: 'One', 2: 'Two', 3: 'Three'}
>>> d.setdefault(5)
>>> d
{1: 'One', 2: 'Two', 3: 'Three', 5: None}
>>> d.setdefault(7, 'Seven')
'Seven'
>>> d
{1: 'One', 2: 'Two', 3: 'Three', 5: None, 7: 'Seven'}
  • update () (Python documents) – takes another dictionary object as an argument and changes the members of the object accordingly:
>>> d = {1:'One', 2:'Two', 3:'Three'}
>>> d2 = {5:'Five', 6:'Six'}
>>> d.update(d2)
>>> d
{1: 'One', 2: 'Two', 3: 'Three', 5: 'Five', 6: 'Six'}
>>> d3 = {1:'0001'}
>>> d.update(d3)
>>> d
{1: '0001', 2: 'Two', 3: 'Three', 5: 'Five', 6: 'Six'}

Collection

“Set” is a type of “unordered” and “mutable” Python that is equivalent to the concept of set in mathematics. Each member of the collection must be unique and one of the “immutable” types. The type of set is presented in the 3x version with a slight difference. In 2x versions, these objects can only be created using the set () class [Python documents], while in Python 3x this can be done simply by using the bracket {} symbol; (Of course, this feature is also ported to version 2.7). In the two examples of the code below, pay attention to how to define and display the collection object: 2x versions:

>>> L = [1, 2, 3, 4, 5]
>>> s = set(L)
>>> type(s)
<type 'set'>
>>> s
set([1, 2, 3, 4, 5])
>>> print s
set([1, 2, 3, 4, 5])
>>> s = {1, 2, 3, 4, 5} # Python 2.7
>>> type(s)
<type 'set'>
>>> s
set([1, 2, 3, 4, 5])

3x versions:

>>> L = [1, 2, 3, 4, 5]
>>> s = set(L)
>>> type(s)
<class 'set'>
>>> s
{1, 2, 3, 4, 5}
>>> print(s)
{1, 2, 3, 4, 5}
>>> s = {1, 2, 3, 4, 5}
>>> type(s)
<class 'set'>
>>> s
{1, 2, 3, 4, 5}

There is no specific syntax for creating or expressing an empty object of set type, and only the set () class – without arguments – should be used. Note that {} stands for an empty dictionary object, not an empty set:

>>> a = {} # Python 2.x
>>> type(a)
<type 'dict'>
>>> b = set()
>>> type(b)
<type 'set'>
>>> b
set([])
>>> a = {} # Python 3.x
>>> type(a)
<class 'dict'>
>>> b = set()
>>> type(b)
<class 'set'>
>>> b
set()

The len () function can also be used to obtain the number of members of a set object:

>>> s = {1, 2, 3, 4, 5}
>>> len(s)
5

Operators for sets There are a number of operators that define a specific set of objects; While they do not behave in this way about other objects. These operators are in fact the implementation of a specific definition in the mathematical concept of sets:

  • | Union: Like A | B is the result of a set that has all the members of set A and set B and has no additional members.
>>> A | B
{'w', 'y', 'q', 't', 'r', 'z', 's', 'v', 'u', 'x'}
  • & Intersection: Like A & B, which is the result of a set that includes only members that are in both set A and set B:
  • Difference: Like A – B, which is the result of a set that includes only members of set A that are not in set B:
>>> A = {'u', 'v', 'w', 'x', 'y', 'z'}
>>> B = {'q', 'r', 's', 't', 'u', 'v', 'w',}
>>> A - B
{'z', 'y', 'x'}
  • Met Symmetric difference: such as A ^ B, which is the result of a set that is equal to the community of the difference between A and B and the difference between B and A, ie: (A-B) | (B-A):
>>> A ^ B
{'q', 'y', 't', 'r', 'z', 's', 'x'}
>>> (A-B) | (B-A)
{'y', 'q', 't', 'r', 'z', 'x', 's'}

The symmetric difference can also be defined as follows:

>>> (A|B) - (B&A)
{'y', 'q', 't', 'r', 'z', 's', 'x'}
  • > Subset: Like A <B, which returns a True value if set A is a subset of set B. Opposite the operator <, for example in the expression A> B, if set A is a superset for set B, returns the value True:
>>> A = {1, 2, 3, 4, 5}
>>> B = {1, 2, 3}
>>> A < B
False
>>> A > B
True

Some general operators can also be used for set objects:

>>> A = {'a', 'b', 'c'}
>>> 'a' in A
True
>>> 'c' not in A
False
>>> A = {1, 2, 3, 4, 5}
>>> B = {1, 2, 3}
>>> A == B
False
>>> C = A
>>> A == C
True
>>> A is C
True

Some functional methods set an object

  • union (Python documents) – Receives a set of objects and returns a new set equal to the community of the object with them:
>>> A = {'a', 'b', 'c'}
>>> B = {1, 2, 3}
>>> {'t', 1, 'a'}.union(A, B)
{'a', 1, 2, 3, 't', 'b', 'c'}
>>> {'t', 1, 'a'} | A | B
{1, 2, 3, 'b', 't', 'a', 'c'}

Similarly, we can use intersection (Python documents) to share, difference () (Python documents) for difference, symmetric_difference (), which is a single argument – for symmetric difference, (issubset () documents And () used the issuperset (both Python documents) – both of which are single arguments – to check for a subset or superset.

>>> A = {'a', 'b', 'c'}
>>> A.clear()
>>> A
set()
  • add (x) [Python Documents] – Adds the immutable object x if it does not already exist in the object of the set:
>>> A = {'a', 'b', 'c'}
>>> A.add(1)
>>> A
{'a', 'c', 1, 'b'}
  • remove (x) [Python Documents] – Removes the x member from the object in the set. If x is not in the set, it reports an error:
>>> A = {'a', 'b', 'c', 1}
>>> A.remove(1)
>>> A
{'c', 'a', 'b'}
>>> A.remove(1)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 1

There is another similar method with the pattern discard (x) [Python documents] which deletes it if x exists; therefore, no error is reported in the absence of x:

>>> A = {'c', 'a', 'b'}
>>> A.discard(1)
>>> A
{'b', 'a', 'c'}
  • pop () Python documents – This method has no arguments and arbitrarily deletes a member of the set and returns it as output. An error is reported when the set is empty:
>>> A = {'a', 'b', 'c'}
>>> A.pop()
'a'
>>> A.pop()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 'pop from an empty set'

frozenset

As stated earlier, a set is a “changeable” object with “immutable” members, and it is because of this variability that we can easily add or remove members by methods. “Frozenset” is a new type of collection. Just as we can represent a tuple object equivalent to an immutable list object; The frozenset can also be thought of as an immutable set object. The frozenset type is the same as the set type, with all its properties except for the variability created using the frozenset () class: 2x versions:

>>> L = [1, 2, 3]
>>> A = frozenset(L)
>>> type(A)
<type 'frozenset'>
>>> A
frozenset([1, 2, 3])

3x versions:

>>> L =[1, 2, 3]
>>> A = frozenset(L)
>>> type(A)
<class 'frozenset'>
>>> A
frozenset({1, 2, 3})

Using the dir () function, you can find out the available methods of the frozenset object:

>>> dir(frozenset) # Python 3.x
['__and__', '__class__', '__contains__', '__delattr__',
'__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__init__',
'__iter__', '__le__', '__len__', '__lt__', '__ne__',
'__new__', '__or__', '__rand__', '__reduce__',
'__reduce_ex__', '__repr__', '__ror__', '__rsub__',
'__rxor__', '__setattr__', '__sizeof__', '__str__',
'__sub__', '__subclasshook__', '__xor__', 'copy',
'difference', 'intersection', 'isdisjoint', 'issubset',
'issuperset', 'symmetric_difference', 'union']

NoneType

This type of object has no value and is created by assigning a constant None to a name:

>>> n = None
>>> type(n)
<class 'NoneType'>
>>> print(n)
None
>>> import sys
>>> sys.getsizeof(a)
16
>>> n = 5
>>> type(n)
<class 'int'>

None in Python 3x is defined as keywords.

Grouping

This section categorizes object types based on some Python definitions.

  • Numeric Types:
1
2
3
4
5
6
7
- int
- long (2.x)
- float
- complex
- Decimal
- Fraction
- bool
  • Sequence Types:
1
2
3
4
5
6
- str
- unicode (2.x)
- bytes (3.x)
- bytearray (3.x/2.6+)
- tuple
- list
  • Immutable Types:
 1
2
 3
 4
 5
 6
 7
 8
 9
10
11
12
- int
- long (2.x)
- float
- complex
- Decimal
- Fraction
- bool
- str
- unicode (2.x)
- bytes (3.x)
- tuple
- frozenset
  • Mutable Types:
1
2
3
4
- bytearray (3.x/2.6+)
- list
- dict
- set
  • Mapping Types:
1
- dict
  • Set Types:
1
2
- set
- frozenset
  • Others:
1
2
3
- zip
- dict_views
- NoneType

In the next lessons, we will get acquainted with other types of ready-in (Built-in). 😊 I hope it was useful

Leave a Reply

Your email address will not be published. Required fields are marked *