The tuple data type  represents an ordered, immutable collection of elements.  Tuples, in Python, share a lot of similarities with lists, however, unlike lists,  tuples cannot be updated once they are created. This makes them suitable for working with fixed sets of data such as coordinates, dates and any other pieces of data that won't change.

In Python, a tuple is simply a sequence of values that are separated by commas. Conventionally, we enclose the elements of a tuple in parentheses to enhance code readability. This makes it easy to distinguish tuples from other data types such as lists, which use square brackets. For example, both of the following tuples are equivalent:

T = 1, 2, 3, 4, 5
T1 = (1, 2, 3, 3, 4, 5)
copy

To initialize an empty tuple, we simply use empty parentheses:

t = ()
copy

We can also use the builtin tuple function, which returns an empty tuple if called without any argument, as shown below:

t = tuple()
copy

Other examples: 

(1, 2, 3)#tuple of integers
('PHP', 'Javascript', 'Html', 'CSS')#tuple of strings
((1.0, 2.0), (3.0, 4.0), (5.0, 6.0))#tuple of tuples
copy

It is, however, worth noting that parentheses are also used in expressions. Example:

(1 + 3)
(2 * 4)
( (2 + 2) * 5) 
copy

This introduces room for ambiguity in some use cases, for example a tuple with only one element  will need to have a trailing comma, otherwise, it will be interpreted as an expression.Example:

(8, )
('Python', )

Consider in the examples above if we  did not add a trailing comma:

ExampleEdit & Run
t = (8)
print( type(t) )

t2 = ('Python')
print( type(t2) )
copy
Output:
<class 'int'> <class 'str'> [Finished in 0.010538201779127121s]

Adding the trailing comma effectively makes it a tuple with a single element:

ExampleEdit & Run
t = (8, )
print( type(t) )

t2 = ('Python', )
print( type(t2) )
copy
Output:
<class 'tuple'> <class 'tuple'> [Finished in 0.010380803607404232s]

Operations on Tuples

Many operations that can be performed on lists, such as concatenation, repetition, and indexing, can also be performed on tuples. However, because tuples are immutable, any operation that appears to modify a tuple actually creates a new tuple, whereas with lists, modifications can be made to the original list without creating a new one.

Concatenation and Repetition

The "+"operator is used to concatenate two  tuples. The syntax is as follows:

tuple1 + tuple2
copy

This operation leads to creation of a new tuple which contains all the elements of tuple1 followed by all the elements of tuple2

ExampleEdit & Run
print( (1, 2) + (3, 4) )

print( ('PHP', 'Javascript', 'CSS') + ('Python', 'Java', 'C++') )
copy
Output:
(1, 2, 3, 4) ('PHP', 'Javascript', 'CSS', 'Python', 'Java', 'C++') [Finished in 0.009992829523980618s]

Repetition, on the other hand, is achieved using the "*" operator. The operator, in this case, takes two operand , the tuple and an integer which specifies the number of time that the tuple will be repeated.  The operation results in a new tuple whose elements are the elements of the tuple operand repeated the number of times specified by the integer operand. 

ExampleEdit & Run
T = (0, )
print( T * 5 )

T = ('Python', 'Java')
print( T * 2 )

T = ((1,3),)
print( 3 * T )
copy
Output:
(0, 0, 0, 0, 0) ('Python', 'Java', 'Python', 'Java') ((1, 3), (1, 3), (1, 3)) [Finished in 0.009899779222905636s]

Tuple Length

The length of a tuple is the total number of elements it contains. For example an empty tuple will have a length of 0, a tuple with one element will have a length of and so forth. We can get the length of a given tuple using the builtin len() function. 

ExampleEdit & Run
T = ()
print( len(T) )

T  = (1, )
print( len(T) )

T = (1, 2, 3, 4, 5)
print( len(T) )
copy
Output:
0 1 5 [Finished in 0.009911860339343548s]

Indexing and Slicing

Like other sequences in Python, you can use indexing to access individual elements in a tuple  through  their index, and  slicing is used to get all elements within a given range of indices.

Indices in Python sequences, including tuples, always starts at 0. The first element in the tuple has an index 0 , the second has an index 1, and so on.

In addition to the positive indices, each element  in a tuple also has a negative index. In this case the indices starts from the back of the tuple and ,move to the front. The last element in the tuple has an index of  -1 , the second last has an index of  -2 , the third last has an index of  -3 , and so on.

The square brackets [] are used for indexing, as well as slicing. In indexing, if we have a tuple T, the syntax is as follows:

T[ index ]
copy

This returns the element at the specified index . 

ExampleEdit & Run

Using positive indexing 

T = ('Python', 'Javascript', 'C++', 'Perl', 'Html', 'CSS', 'Kotlin', 'Java')

print( T[0] )  #get the first element
print( T[1] ) #get the second element
print( T[4] ) #get the fifth element
print( T[ len(T) - 1 ] ) #get the last element
copy
Output:
Python Javascript Html Java [Finished in 0.010457458905875683s]

In the following examples , we use negative indexing.

ExampleEdit & Run
T = ('Python', 'Javascript', 'C++', 'Perl', 'Html', 'CSS', 'Kotlin', 'Java')

print( T[-1] ) #get the last element

print( T[-2] ) #get the second-last element

print( T[-3] ) #get the third-last element

print( T[ -len(T) ] ) #get the first element
copy
Output:
Java Kotlin CSS Python [Finished in 0.01036151498556137s]

Slicing ,as we said, is used to access the elements  in a given range of indices. If we have tuple T, the syntax is as follows:

T[start : stop : step]
copy

Slicing returns a new tuple that contains all the elements of the original tuple whose indices begin at start and end at stop, without including the value at stop. The step value determines the interval between the selected indices.

if any of the three slicing parameters is omitted, Python will use default values; start defaults to 0, stop defaults to the length of the tuple, and step defaults to 1.

ExampleEdit & Run
T = (1, 2, 3, 4, 5, 6, 7, 8, 9)

print( T[ : 5] )  #start defaults to 0 and step to 1
print( T[4 : ] ) #stop defaults to tuple's length and step 1
print( T[ 0:: 2 ] )  #stop  defaults to the tuple's length
print( T[ : ] ) #ommiting all parameters results in the same tuple
print( T[ :: -1 ] )  #using negative step to reverse the tuple
copy
Output:
(1, 2, 3, 4, 5) (5, 6, 7, 8, 9) (1, 3, 5, 7, 9) (1, 2, 3, 4, 5, 6, 7, 8, 9) (9, 8, 7, 6, 5, 4, 3, 2, 1) [Finished in 0.009968535974621773s]

It is ,however,  worth noting that we cannot perform index or slice assignments in tuples like in lists and other mutable types. Doing this will raise a TypeError as shown below:

ExampleEdit & Run
T = (1, 2, 3, 4, 5, 6, 7, 8, 9)

T[0] = 0 #TypeError: 
copy
Output:
Traceback (most recent call last):   File "<string>", line 3, in <module> TypeError: 'tuple' object does not support item assignment [Finished in 0.009759429842233658s]

However , in cases where a tuple contains a mutable data type such as a list as its element, the mutable object can be changed without necessarily changing the tuple itself.

ExampleEdit & Run
T = ([1, 2], [3, 4], [5, 6])

T[0][0] = 9
T[0][1] = 9

print( T )
copy
Output:
([9, 9], [3, 4], [5, 6]) [Finished in 0.009747881442308426s]

In the above case, there is no creation of a new tuple since we are not changing the tuple itself but rather the list at index 0 of the tuple. This is because the tuple stores references to its elements and not the actual data.

Membership Operations

We can check whether a tuple contains a given element using the in operator. The syntax is as follows:

x in <tuple>
copy

This operation returns True if element x is in the tuple, otherwise False.

ExampleEdit & Run
T = ('Javascript', 'Python', 'C++', 'Perl', 'Html', 'CSS', 'Kotlin', 'Java')

print( 'Python' in T)
print( 'C#' in T )
copy
Output:
True False [Finished in 0.009814378805458546s]

The not in operator is the opposite of the in operator, it returns True if the item is not in the tuple and False otherwise. The syntax is as follows:

x not in <tuple>
copy
ExampleEdit & Run
T = ('Javascript', 'Python', 'C++', 'Perl', 'Html', 'CSS', 'Kotlin', 'Java')

print( 'Python' not in T )
print( 'C#' not in T )
copy
Output:
False True [Finished in 0.009735587984323502s]

Casting other types to tuples

The builtin  tuple() function can be used with a value from sequential types such as lists sets and strings  in order to turn them to tuples.

ExampleEdit & Run
print( tuple( [1, 2, 3, 4, 5] ) ) #list to tuple

print( tuple( {'Python', 'PHP', 'CSS', 'Html'} ) ) #set to tuple

print( tuple('Python') ) #string to tuple
copy
Output:
(1, 2, 3, 4, 5) ('PHP', 'Html', 'CSS', 'Python') ('P', 'y', 't', 'h', 'o', 'n') [Finished in 0.00970468670129776s]

Tuple Methods

Due to their immutable nature, tuples support a limited set of methods. 

index()

Syntax:

T.index(x)
copy

This method returns the index of the leftmost occurrence of in tuple T. A ValueError is raised if x is not found in the tuple.

ExampleEdit & Run
T = ('Python', 'CSS', 'Javascript', 'C#', 'C++', 'Java')

print( T.index('Python') )
print( T.index('Java') )
print( T.index('C#') )
print( T.index('PHP') ) #ValueError
copy
Output:
0 5 3 Traceback (most recent call last):   File "<string>", line 6, in <module> ValueError: tuple.index(x): x not in tuple [Finished in 0.00991014949977398s]

count()

Syntax:

T.count(x)
copy

Returns the number of times that item occurs in tuple T.  

ExampleEdit & Run
T = ('Python', 'CSS', 'Javascript', 'Python', 'C#', 'C++', 'Java',  'CSS', 'Python' )

print( T.count('Python') )
print( T.count('C++') )
print( T.count('CSS') )
print( T.count('PHP') )
copy
Output:
3 1 2 0 [Finished in 0.00970175489783287s]