payment by upi: sinhamit@icici or payment by bank account name: amit kumar sinha, account number: 2646728782 IFSC code: KKBK0005660 SWIFT: KKBKINBB

Please support if you like my work by payment through upi: sinhamit@icici or payment by bank

account name: Amit Kumar Sinha,
account number: 2646728782
IFSC code: KKBK0005660
SWIFT: KKBKINBB


Complex Nesting of Lists, Tuples, Dictionaries   in Category: Python   by amit

🕙 Posted on 2023-08-08 at 18:17:27     Read in Hindi ...


Nested Lists, Nested Tuples, and Nested Dictionaries

my_string = "[ 'Hello', 'World' ]"
print( my_string )
print( my_string[0] )
print( len( my_string ), len( my_string[0] ) )
print( type( my_string ), type( my_string[0] ) )

[ 'Hello', 'World' ]
[
20 1
<class 'str'> <class 'str'>

    The above code is an example of a string literal, and not list, because each character is enclosed within a pair of double quotes. In previous page, you have seen that an empty string has 0 (zero) length, and therefore, extracting a single character with [0] outputs IndexError: string index out of range. However, a string literal with a single character (even a blank space enclosed within a pair of single/double quotes), always returns a character, when extracted with [0]. Here, 0 (zero) is the index number of first character in a string literal. Thus, it is funniest thing that you can add as many [0] afterwards the string literal or a variable name which is assigned with that string literal (except empty string).

print( my_string[0][0][0][0] )   # Always outputs [ no matter how many [0] is added.

print( ' '[0][0][0][0] )   # Always outputs   (a blank space) not visible in Console or VSCode Editor Terminal. When no ERROR is shown while executing the code, it should be understood (clear) that the code has been executed success­fully!

print( 'Hello World'[1][0][0][0] )   # Always outputs e (the second character in the string literal) no matter how many [0] is added.

    As shown above, string literals have only one level of sequence, therefore, only one pair of square brackets is required. To know how extrac­tion and slicing are performed in Python, visit previous page.

    Caution: You can add more and more pairs of square brackets (as shown above), but you should be careful and you must add only as much pairs of square brackets, as there are levels of sequences (NESTING) in a sequence data-type (that is, strings, lists, tuples, and diction­aries). In the following example, you can see that a string literal is only one level of sequence, and therefore, you cannot extract second index from a single character.

print( 'Hello World'[1][1] )   # Outputs IndexError: string index out of range (there is only one character extracted from 'Hello World'[1], which afterwards can only be accessed by adding [0]).

    In previous page, you have seen many literals of list and tuple data-type, which contain only one character in each item/element. Those are described therein, to explain you that slice() (and slicing by using colon symbols within a pair of square brackets) always returns one or more individual item/element in respective data-type. Slicing cannot extract individual character/item from the value, but returns whole item/element, as explained herein below:

my_list = ['Hello', 'World']

print( my_list[0] )     # Outputs Hello (first item)
print( my_list[1] )     # Outputs World (second item)
print( my_list[-1] )    # Outputs World (last item)
print( my_list[-2] )    # Outputs Hello (second last item)

print( my_list[:] )     # Slicing from first item to last item
print( my_list[::] )    # Slicing from first item to last item, with no step skipped

    The above examples are described herein to explain you that like numbers (integers and floats), boolean (True / False), None (null in other programming languages), string literals are also scalar data-type, no matter it is sequence of characters. However, other data-types, such as lists, tuples, diction­aries are complex data-type, and can contain other data-type items/elements in them.

Nesting

    The value of each item/element in a list, tuple, or dictionary has its own identity (you can check them with id() function). Thus, when lists, tuples and diction­aries have items of values other than numbers, boolean and None, then again individual item or character (from that item of respective list, tuple or dictionary) can be accessed by adding index numbers within a pair of square brackets. This is called NESTING, where an item in a list, tuple, or dictionary can contain other complex data-types.

    In the above and following examples, the list literal, ['Hello', 'World'] has only two items/elements, namely, 'Hello' (with index number 0 or -2) and 'World' (with index number 1 or -1). Both items in each list literal are of string data-type. You can also get index number of first and last items with the help of len() function (See previous page).

    Now, you can go one or more level further in lists and other sequence data-type literals or variable names, which have strings, lists, tuples, diction­aries NESTED within them, by adding the index number (or exact key in case of diction­aries) within one or more pairs of square brackets.

my_list = ['Hello', 'World']

print( my_list[0][0] )     # Outputs H (first character from the first item)
print( my_list[0][1] )      # Outputs e (second character from the first item)

print( my_list[1][0] )      # Outputs W (first character from the second item)
print( my_list[1][1] )       # Outputs o (second character from the second item)

print( my_list[0][-1] )     # Outputs o (last character from the first item)
print( my_list[1][-1] )      # Outputs d (last character from the second item)

    If an item/element in a list, tuple, or dictionary is other than string data-type, then you can again go further, and add more pairs of square brackets, to access or extract individual items/elements, as shown below, and so on... If a nested item is of dictionary data-type, then you have to place exact key name, instead of index number of that item.

complex_list = [
  (11, 22, 33),     # nested tuple
  {
    "fword": "hello",
    'lword': 'world',
    "length": 3
  },               # nested dictionary
  (
    ['a', 'b', 'c'],
    ['d', 'e', 'f']
  )                 # nested lists in nested tuple
]

print( complex_list )
print( complex_list[0], type( complex_list[0] ) )
print( complex_list[1], type( complex_list[1] ) )
print( complex_list[2], type( complex_list[2] ) )

print( complex_list[0][1], type( complex_list[0][1] ) )
print( complex_list[1]["fword"], type( complex_list[1]["fword"] ) )
print( complex_list[2][1], type( complex_list[2][1] ) )

    The above example is a typical illust­ration of NESTING of different data-types, into one another, and the output is shown below. In the above example, the variable name, complex_list (which may be of tuple data-type, if you write parent­heses instead of square brackets) has only three items in it. The first and third items are tuple literals, and the second item is a dictionary literal. The third item also contains two list items in it.

[(11, 22, 33), {'fword': 'hello', 'lword': 'world', 'length': 3}, (['a', 'b', 'c'], ['d', 'e', 'f'])]
(11, 22, 33) <class 'tuple'>
{'fword': 'hello', 'lword': 'world', 'length': 3} <class 'dict'>
(['a', 'b', 'c'], ['d', 'e', 'f']) <class 'tuple'>
22 <class 'int'>
hello <class 'str'>
['d', 'e', 'f'] <class 'list'>

    In the above output you can see that the first line shows the whole complex_list. Second, third and fourth lines show each item/element in the variable name complex_list. Fifth, sixth and seventh lines show respective nested item, which are extracted by adding one more pair of square brackets. You can also notice that the exact key name is used inside the pair of square brackets, when there is a dictionary data-type.

    When the extracted (nested) item/element is of boolean, integer, float or None data-type, you cannot go further to extract further nested item or characters, as the case may be. When the extracted (nested) item is of string data-type, you can play as mentioned at the top of this page, but you can only go one more further level, as shown below:

Continued from Above Example

print( complex_list[1]["fword"][0], type( complex_list[1]["fword"][0] ) )   # Outputs h <class 'str'> (first letter of 'hello')

    You will get IndexError: string index out of range or KeyError: 0 (as the case may be) when you write 5 (wrong index number), or 0 instead of "fword" (wrong key name) in above code. You must have very careful while extracting or slicing any complex list, tuple or dictionary literal, as illust­rated above.

Continued from Above Example

print( complex_list[2][0][1], type( complex_list[2][0][1] ) )   # Outputs b <class 'str'> (second item/element of ['a', 'b', 'c'])

    Also, different data-types have different methods for them. Therefore, when there are string or tuple data-type literals (or variable names) are present in any complex literal, those will be immutable. When there are list or dictionary data-type literals are present, individual items/elements in them can be changed with respective index number or respective key name.

Continued from Above Example

complex_list[1]["lword"] = "public"
complex_list[2][0][1] = "x"
print( complex_list )   # Outputs [(11, 22, 33), {'fword': 'hello', 'lword': 'public', 'length': 3}, (['a', 'x', 'c'], ['d', 'e', 'f'])]

complex_list[0][1] = 55   # Comment this line to avoid ERROR
print( complex_list )   # Outputs TypeError: 'tuple' object does not support item assignment

complex_list[1][1] = 55
print( complex_list )   # Outputs [(11, 22, 33), {'fword': 'hello', 'lword': 'public', 'length': 3, 1: 55}, (['a', 'x', 'c'], ['d', 'e', 'f'])] (A new key will be added in NESTED dictionary.)

complex_list[2][1] = 55   # Comment this line to avoid ERROR.
print( complex_list )   # Outputs TypeError: 'tuple' object does not support item assignment

complex_list[2][1][1] = 55
print( complex_list )   # Outputs [(11, 22, 33), {'fword': 'hello', 'lword': 'public', 'length': 3, 1: 55}, (['a', 'x', 'c'], ['d', 55, 'f'])]

    From above five examples, you can see that where any item/element (no matter how deep it is nested inside,) is mutable, then nested values can be changed accor­dingly. However, when any item/element is immutable (not changable), then you will get ERROR as shown above.

len(), index(), count()

    In previous page, you have already learned about len() built-in function, and index() and count() methods, which can be applied on strings, lists and tuples (also on bytearray and bytes data-types). These two methods are not available for dictionary data-type, hence, you cannot get desired result from these two methods, when applied on any (NESTED) dictionary and you will also get ERROR.

Continued from Above Example

print( len( complex_list[1] ) )   # Outputs 4 (After above modification, an item/element has been added to NESTED dictionary, and value returned from len() function will be changed.)

print( len( complex_list ) )   # Outputs 3 (length of parent list)

print( len( complex_list[0] ) )   # Outputs 3 (length of first NESTED tuple)

print( len( complex_list[2] ) )   # Outputs 2 (length of second NESTED tuple)

print( len( complex_list[2][0] ) )   # Outputs 3 (length of first NESTED list inside second NESTED tuple)

print( len( complex_list[2][1] ) )   # Outputs 3 (length of second NESTED list inside second NESTED tuple)

    Similarly, you can search for specific item or character(s) and its occurr­ences with the help of index() and count() methods in any NESTED list or NESTED tuple, but not in any NESTED dictionary. While devel­oping any WEB-APP (website with Python or any other program­ming languages), or other applications, such CLI (command-line interface) or GUI (graphic-user interface), you (including all progra­mmers) must have to examine and script codes carefully!

    Later, you will also learn how to create a PNG (portable network graphic) images with the help of NESTED LISTS and openCV module.


Leave a Comment: