Python Data Presistence – Variables

Python Data Presistence – Variables

When you use an object of any of the above types – of any type for that matter – (as a matter of fact everything in Python is an object!) it is stored in the computer’s memory. Any random location is allotted to it. Its location can be obtained by the built-in id ( ) function.

Example

>>> id(10)
1812229424
>>> id(‘Hello’)
2097577807520
>>> id([10,20,30])
2097577803464

However, order to refer to the same object repetitively with its id() is difficult. If a suitable name (by following rules of forming identifier) is given to an object, it becomes convenient while referring to it as and when needed. To bind the object with a name, the ‘=’ symbol is used. It is called the assignment operator.

Here, an int object 5 is assigned a name ‘radius’. The id( ) of both is same.

Example

>>> id(5)
1812229264
>>> radius=5
>>> id(radius)
1812229264

The name ‘radius’ can now be used in different expressions instead of its id ( ) value.

Example

>>> diameter=radius*2
>>> diameter
10
>>> area=3. 142*radius*radius
>>> area
78.55
>>> circumference=2*3.142*radius
>>> circumference
31.419999999999998

Dynamic Typing

Python is a dynamically typed language. This feature distinguishes it from C Family languages like C, C++, Java, and so on. These languages are statically typed. What is the difference?

The difference is the manner in which a variable behaves. In statically typed languages, the variable is in fact a named location in the memory. Moreover, it is configured to store data of a certain type before assigning it any value. Data of any other type is not acceptable to the respective language compiler. Type of Variable is announced first, and data of only that type is acceptable. This makes these languages statically typed.

Look at the following statements in a Java program. A string variable is declared and assigned a string value. However, if we try storing the value of any other type then the Java compiler reports an error.

Example

String somevar;
somevar=”some string value”;
somevar=999;

Java Compiler error

Error: incompatible types: int cannot be converted to java. lang.String

On the other hand, a variable in Python is not bound permanently to a specific data type. In fact, it is only a label to an object in memory. Hence, Java-like prior declaration of variable’s data type is not possible, nor is it required. In Python, the data assigned to a variable decides its data type and not the other way round.

Let us define a variable and check its id ( ) as well as type ( ).

Example

>>> somevar=’some string value’
>>> id(somevar)
2166930029568
> > > type(somevar)
<class ‘str’>

‘somevar’ is a string variable here. But it’s just a label. So you can put the same label on some other object.

Let us assign an integer to Somevar’ and check id () as well as type () again.

Example

>>> somevar=999
>>> id(somevar)
2166929456976
>>> type(somevar)
<class 1int’>

Two things to note here:

  1. You didn’t need a prior declaration of variable and its type.
  2. Variable’s type changed according to data assigned to it. That’s why Python is called a dynamically typed language.

Sequence Operators

As described earlier, string, list, and tuple objects are sequence types. Obviously, arithmetic operators won’t work with them. However, the symbols ‘+’ and can. In this context, they are defined as concatenation and repetition operators respectively.
The concatenation operator (‘+’) appends the contents of the second operand to the first. Of course, both operands must be of the same type.

Example

>>> #concatenation of strings
>>> str1=’Hello World.’
>>> str2=’Hello Python.’
> > > str1+str2
‘Hello World.Hello Python.’
> > > #concatenation of lists
. . .
>>> list1= [1,2,3,4]
> > > list2= [‘one’, ‘two’, ‘three’ ,’four’ ]
> > > listl+list2
[1, 2 , 3 , 4 , ‘ one ‘ , ” two ‘ , ‘ three ‘ , ‘ four’]
>>> ttconcatenation of tuples
. . .
>>> tup1=(1,2,3,4)
>>> tup2=(‘one’,’two’,’three’, ‘four’)
>>> tupl+tup2
(1, 2 , 3, 4, ‘one’, ‘two’, ‘three’, ‘ four’)

Repetition operator(‘*’) concatenates multiple copies of a sequence. The sequence to be replicated is the first operand, the second operand is an integer that specifies the number of copies.

Example

>>> #repetition operator with string
. . .
>>> strl=’Hello.’
>>> str1*3
‘Hello.Hello.Hello.’
>>> #repetition operator with list
. . .
>>> list1= [1,2,3,4]
>>> list1*3
[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
>>> #repetition operator with tuple
tup1=(1,2,3,4)
>>> tup1*3
(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4)

Index operator (‘[]!) extracts an item at a given position in a sequence. As you know, the sequence is an ordered collection of items and each item has a positional index starting from 0. The expression seq[i] fetches ill item from a given sequence.

Example

>>> #indexing of string
. . .
>>> str1=’Monty Python and the Holy Grail ‘
>>> str1 [21]
‘ H ‘
>>> #indexing of list
. . .
>>> list1=[l,2,3,4,5,6,7,8,9,10]
>>> list1 [6]
7
>>> list1= [‘Python ‘ , ‘‘Java’, ‘C++’, ‘Ruby’, ‘Kotlin’]
>>> .list1 [3]
‘Ruby’
>>> #indexing of tuple
. . .
>>> tup1=(-50, 3.142, 2+3j, True, 50
>>> tup1[2]
(2+3j) )

Slice operator (‘[:]’) fetches a part of the sequence object. The expression has two integers on either side of the symbol inside square brackets. The first integer is an index of the first item in the sequence and the second integer is an index of the next item up to which slice is desired. For example seqflj] returns items from i* position to (j-l)the position. The first integer is 0 by default. Second integer defaults to the last index of the sequence. Remember index starts from 0.

Example

>>> #slicing of string
… strl=’Monty Python and the Holy Grail’
>>> strl [13:16]
‘and’
>>> listl=[‘Python’, ‘Java’, ‘C++’, ‘Ruby’, ‘Kotlin’]
>>> listl [1:3]
[‘Java’, ‘C++’]
>>> tupl=(-50, 3.142, 2 + 3j, True, 50)
>>> tupl[2:4]
( (2 + 3j), True)

There are two ‘Membership’ operators in Python. The in operator checks if an operand exists as one of the items in a given sequence and returns True if so, otherwise, it returns False. The not-in operator does the opposite. It returns False if the operand doesn’t belong to a given sequence, otherwise it returns True.

Example

>>> #membership operator with string
. . .
>>> str1=’Monty Python and the Holy Grail’
>>> ‘Holy’ in str1
True
>>> ‘Grill’ not in str1
True
>>> #membership operator with list
. . .
>>> list1=[‘Python’, ‘Java’, ‘C++’, ‘Ruby’, ‘Kotlin’]
>>> ‘C#’ in list1
False
>>> ‘Ruby’ not in list1
False
>>> #membership operator with tuple
. . .
>>> tup1=(-50, 3.142, 2+3j, True, 50)
>>> 3.142 in tup1
True
>>> 3.142 not in tup1
False

Mutability

As already mentioned, everything in Python is an object. A Python object is either mutable or immutable. What is the difference?
To put it simply, the object whose contents can be changed in place is mutable. As a result, changes are not possible in the contents of immutable objects. Of the built-in objects numbers, string, and tuple objects are immutable. On the other hand, list and dictionary objects are mutable.

Let us try to understand the concept of mutability with the help of the id() function that we have earlier used. First, define a variable and assign an integer to it.

Example

>>> x=100
>>> id(x)
1780447344

Remember that a variable is just a label of the object in memory. The object is stored in a location whose id() is given as shown in example 1.31 above. (The location is allotted randomly. So, when you try it on your machine, it may be different.) To understand what goes on inside the memory, have a look at the diagram (figure 1.4) below. Figure 1.4 (a) shows a label assigned to an integer object 100.
Next, assign x to another variable y.

Python Data Presistence - Variables chapter 1 img 1

Example

>>> y=x
>>> id(y)
1780447344
>>> y
100

Figure 1.4 (b) shows that id() of y is the same as id ( ) of x. It means both x and y are labels of the same object in memory, in this case, the number 100.
Now, increment x by 1 (x=x+l). A new integer object 101 is located at a different location and it is bound to name x. Now x label is detached from 100 but y still remains on 100. (refer figure 1.4 (c))

Example

>>> x=x+1
>>> X
101
>>> id(x)
1780447376
>>> id(y)
1780447344

id (x) has changed but id (y) remains as earlier.

It is clear that the location containing object 100 doesn’t get replaced by 101, instead, it is stored in a new location. Hence, we say that a Number object is immutable. String and tuple objects are also immutable. If we try to change the sequence of characters in a string or any of the items in a tuple, the TypeError message appears effectively meaning that items in a string/tuple sequence can’t be altered because they are immutable.

Example

>>> str1=’Hello World’
>>> str1[6]
‘ W’
>>> str1 [6] = ‘ z ‘
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
TypeError: ‘str’ object does not support item
assignment
>>> tup1=(-50, 3.142, 2+3j, True, 50)
>>> tup1[1]
3.142
>>> tup1[1]=2.303
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
TypeError: ‘tuple’ object does not support item assignment

This restriction doesn’t apply to list or dictionary objects. You can add, remove, or modify a list or dictionary. Hence, they are mutable.
Following code demonstrates how an item in list/dictionary is modified.

Example

>>> list1=[‘python’, ‘java’,’C++’ , ‘Ruby’, ‘kotlin’]
>>> list[2] = ‘c#’
>>> list1
[‘Python’ , ‘Java’ , ‘C#’ , ‘Ruby’ , ‘ Kotlin’ ]
>>> dict1= {“Mumbai’ , : ‘Maharastra’ , ‘Hyderebad’ : ‘Telangana’ , ‘patna’ , : ‘Bihar’}
>>>dict1 [‘Hyderabad’ ] = ‘Andhra pradesh’
>>>dict1
{‘Mumbai’ : ‘ Maharastra’ , ‘Hyderabad’ : ‘Andhra pradesh’ ‘patna’ : ‘Bihar’ }

Addition/removal of items in list and dictionary is being explained later in this chapter. That brings us to one of the questions left unanswered earlier. What is the difference between list and tuple? Now the answer is clear. Tuple is immutable. List is mutable.