Advanced Python List Data Type| Part – II

Advanced Python List Data Type| Part - II
Advanced Python List Data Type| Part – II

Hey! Guys this is our “Advanced Python List Data Type| Part – II”, post, where we are going to dicussing lots of list data type in python.

Advanced Python List Data Type.

The enumerate() function in Python is a useful built-in method that allows you to iterate over the indexes and elements of a list (or any iterable) simultaneously. It returns an iterator that yields tuples containing both the index and the corresponding element from the iterable.

Here’s how it works, along with an example:

Syntax:

    enumerate(iterable, start=0)
  • iterable: The iterable (e.g., list, tuple, string) over which to iterate.
  • start (optional): The value from which the index should start. By default, it starts from 0.

Example:

    my_list = ['a', 'b', 'c', 'd', 'e']

    for index, element in enumerate(my_list):
        print(f"Index: {index}, Element: {element}")

# output:
Index: 0, Element: a
Index: 1, Element: b
Index: 2, Element: c
Index: 3, Element: d
Index: 4, Element: e

Explanation:

  • In this example, we have a list my_list containing some elements.
  • We use a for loop to iterate over the list using enumerate().
  • Inside the loop, enumerate(my_list) returns an iterator that yields tuples containing index-element pairs.
  • The loop unpacks each tuple into the variables index and element.
  • We then print the index and the corresponding element for each iteration.

Advanced Usage:

You can also specify a starting index for enumerate():

    my_list = ['a', 'b', 'c', 'd', 'e']

    for index, element in enumerate(my_list, start=1):
        print(f"Index: {index}, Element: {element}")

# output:
Index: 1, Element: a
Index: 2, Element: b
Index: 3, Element: c
Index: 4, Element: d
Index: 5, Element: e

Explanation:

  • By specifying start=1, the index starts from 1 instead of the default 0.
  • This is useful when you want the index to match a specific numbering convention, such as starting from 1 instead of 0.

zip(): Combines multiple lists into a single iterable:

In Python, the zip() function is used to combine multiple iterables (such as lists, tuples, or other iterable objects) into a single iterator of tuples. Each tuple contains elements from corresponding positions in the input iterables. If the input iterables are of different lengths, the resulting iterator will only contain tuples up to the length of the shortest input iterable.

The syntax of the zip() function is as follows:

    zip(iterable1, iterable2, ...)

Below are 5 examples to help you understand zip function more clearly.

i. Basic Usage:


    list1 = [1, 2, 3]
    list2 = ['a', 'b', 'c']
    zipped = zip(list1, list2)
    print(list(zipped))

# output:
[(1, 'a'), (2, 'b'), (3, 'c')]

Explain: The zip() function takes two or more iterables (in this case, list1 and list2) and pairs their elements together. It returns an iterator of tuples where each tuple contains elements from corresponding positions in the input iterables.

ii. Different Length Lists:

    list1 = [1, 2, 3]
    list2 = ['a', 'b']
    zipped = zip(list1, list2)
    print(list(zipped))

# output:
[(1, 'a'), (2, 'b')]

Explain: If the input lists are of different lengths, the resulting iterator will contain tuples only up to the length of the shortest input list.

iii. Unzipping a List of Tuples:


    pairs = [(1, 'a'), (2, 'b'), (3, 'c')]
    unzipped = list(zip(*pairs))
    print(unzipped)

# output:
[(1, 2, 3), ('a', 'b', 'c')]

Explain: By using zip(*pairs), the * operator unpacks the list of tuples pairs into separate arguments to zip(), effectively transposing the list of tuples.

iv. Iterating Over Zipped Lists:


    list1 = [1, 2, 3]
    list2 = ['a', 'b', 'c']
    for num, letter in zip(list1, list2):
        print(f"Number: {num}, Letter: {letter}")

output:
Number: 1, Letter: a
Number: 2, Letter: b
Number: 3, Letter: c

Explain: You can iterate over the zipped lists directly in a loop, extracting elements from each tuple as needed.

v. Creating a Dictionary from Zipped Lists:

    key = ['a', 'b', 'c']
    values = [1, 2, 3]
    dictionary = dict(zip(key, values))
    print(dictionary)

# output:
{'a': 1, 'b': 2, 'c': 3}

Explain: By zipping together lists of keys and values, you can easily create a dictionary where each key is paired with its corresponding value.


sorted() and sort(): sorting lists

sorted() function and the sort() method are utilized to sort lists, ranging from basic sorting of numbers and strings to more advanced sorting of tuples and custom objects.

Let’s explore five examples demonstrating the usage of the sorted() function and the sort()

i. Sorting a List of Numbers in Ascending Order (Basic)


    numbers = [5, 2, 8, 1, 3]
    sorted_numbers = sorted(numbers)
    print(sorted_numbers)

# output:
[1, 2, 3, 5, 8]

Explain:

  • In this basic example, we have a list of numbers numbers.
  • We use the sorted() function to create a new list sorted_numbers containing the same elements as numbers but sorted in ascending order.
  • The original list numbers remains unchanged.
  • The output will be [1, 2, 3, 5, 8], showing the numbers sorted in ascending order.

ii. Sorting a List of Strings in Alphabetical Order (Basic)

    fruits = ["apple", "orange", "banana", "kiwi"]
    sorted_fruits = sorted(fruits)
    print(sorted_fruits)

# output:
['apple', 'banana', 'kiwi', 'orange']

Explain:

  • Here, we have a list of strings fruits.
  • We use the sorted() function to create a new list sorted_fruits containing the strings sorted in alphabetical order.
  • The original list fruits remains unchanged.
  • The output will be ['apple', 'banana', 'kiwi', 'orange'], showing the fruits sorted in alphabetical order.

iii. Sorting a List of Tuples by a Specific Element (Intermediate)

    student_records = [("Alice", 85), ("Bob", 90), ("Charlie", 75), ("David", 80)]
    sorted_records = sorted(student_records, key=lambda x: x[1], reverse=True)
    print(sorted_records)

# output:
[('Bob', 90), ('Alice', 85), ('David', 80), ('Charlie', 75)]

Explain:

  • In this example, we have a list of tuples student_records, where each tuple represents a student’s name and their corresponding score.
  • We use the sorted() function with a custom key function to sort the tuples based on the second element (the score).
  • By setting reverse=True, we sort the list in descending order of scores.
  • The output will be [('Bob', 90), ('Alice', 85), ('David', 80), ('Charlie', 75)], showing the student records sorted by score in descending order.

iv. Sorting a List of Custom Objects (Intermediate)

    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age

        def __repr__(self):
            return f"Person(name='{self.name}', age={self.age})"

    people = [Person("Alice", 25), Person("Bob", 30), Person("Charlie", 20)]
    sorted_people = sorted(people, key=lambda x: x.age)
    print(sorted_people)

# output:
[Person(name='Charlie', age=20), Person(name='Alice', age=25), Person(name='Bob', age=30)]

Explain:

  • Here, we define a Person class representing individuals with a name and an age.
  • We create a list people containing instances of the Person class.
  • We use the sorted() function with a lambda function as the key to sort the list of Person objects based on their ages.
  • The output will display the Person objects sorted by age in ascending order.

v. Sorting a List In-Place using the sort() Method (Advanced)


numbers = [5, 2, 8, 1, 3]
numbers.sort(reverse=True)
print(numbers)

# output:
[8, 5, 3, 2, 1]
  • In this advanced example, we have a list of numbers numbers.
  • We use the sort() method on the list itself to sort the numbers in descending order (reverse=True).
  • Unlike sorted(), which returns a new sorted list, sort() sorts the list in-place.
  • The original list numbers is modified, and the output will be [8, 5, 3, 2, 1], showing the numbers sorted in descending order.

reverse(): reversing the order of elements in a list

reverse() method can be used to reverse the order of elements in a list, from basic scenarios with numbers and strings to more advanced cases with tuples, lists of lists, and custom objects.

Below are five examples demonstrating the usage of the reverse() method:

i. Reversing a List of Numbers (Basic)

    numbers = [1, 2, 3, 4, 5]
    numbers.reverse()
    print(numbers)

# output:
[5, 4, 3, 2, 1]      

Explain:

  • In this basic example, we have a list of numbers numbers.
  • We use the reverse() method to reverse the order of elements in the list in-place.
  • The original list numbers is modified, and the output will be [5, 4, 3, 2, 1], showing the reversed list of numbers.

ii. Reversing a List of Strings (Basic)


    words = ["apple", "banana", "kiwi", "orange"]
    words.reverse()
    print(words)

# output:
['orange', 'kiwi', 'banana', 'apple'] 

Explain:

  • Here, we have a list of strings words.
  • We use the reverse() method to reverse the order of elements in the list in-place.
  • The original list words is modified, and the output will be ['orange', 'kiwi', 'banana', 'apple'], showing the reversed list of strings.

iii. Reversing a List of Tuples (Intermediate)

    coordinates = [(1, 2), (3, 4), (5, 6)]
    coordinates.reverse()
    print(coordinates)

# output:
[(5, 6), (3, 4), (1, 2)]

Explain:

  • In this example, we have a list of tuples coordinates, where each tuple represents a coordinate pair.
  • We use the reverse() method to reverse the order of tuples in the list in-place.
  • The original list coordinates is modified, and the output will be [(5, 6), (3, 4), (1, 2)], showing the reversed list of tuples.

iv. Reversing a List of Lists (Intermediate)

    matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    matrix.reverse()
    print(matrix)

# output:
[[7, 8, 9], [4, 5, 6], [1, 2, 3]]

Explain:

  • Here, we have a list of lists matrix, representing a 2D matrix.
  • We use the reverse() method to reverse the order of sublists (rows) in the list in-place.
  • The original list matrix is modified, and the output will be [[7, 8, 9], [4, 5, 6], [1, 2, 3]], showing the reversed list of lists.

v. Reversing a List of Custom Objects (Advanced)

    class Person:
        def __init__(self, name):
            self.name = name

        def __repr__(self):
            return f"Person(name='{self.name}')"

    people = [Person("Alice"), Person("Bob"), Person("Charlie")]
    people.reverse()
    print(people)

# output:
[Person(name='Charlie'), Person(name='Bob'), Person(name='Alice')]

count() and index():

The count() and index() methods are useful list methods in Python for counting occurrences of elements and finding their indices, respectively.

Let’s delve into these advanced list methods with 5 examples:

i. Using count() to Count Occurrences of Elements

    numbers = [1, 2, 3, 1, 4, 1, 5]
    count_of_ones = numbers.count(1)
    print("Count of '1' in the list:", count_of_ones)

# outpt

Count of '1' in the list: 3

Explain:

  • In this example, we have a list of numbers numbers.
  • We use the count() method to count the occurrences of the element 1 in the list.
  • The method returns the count of occurrences of the specified element.
  • The output will be Count of '1' in the list: 3, indicating that the element 1 appears three times in the list.

ii. Finding the index of the first occurrence:

    my_list = [1, 2, 3, 4, 2, 5, 2]
    index_2 = my_list.index(2)
    print("Index of the first occurrence of 2:", index_2)

# output:
Index of the first occurrence of 2: 1

Explain:

In the above example, the list my_list contains the element 2 at index 1 (the second element). The index() method is used to find the index of the first occurrence of 2, which is 1.

iii. Counting occurrences of a string in a list of strings:

    my_list = ["apple", "banana", "apple", "orange", "apple"]
    count_apple = my_list.count("apple")
    print("Number of occurrences of 'apple':", count_apple)

# output:
Number of occurrences of 'apple': 3

Explain:

In the above example, the list my_list contains three occurrences of the string 'apple'. The count() method is used to count the number of times 'apple' appears in the list, which is 3.

iv. Finding the index of the first occurrence of a substring:

    my_list = ["apple", "banana", "orange", "grape", "pineapple"]
    index_pineapple = my_list.index("pineapple")
    print("Index of the first occurrence of 'pineapple':", index_pineapple)

# output:
Index of the first occurrence of 'pineapple': 4

Explain:

In the above example, the list my_list contains the string 'pineapple' at index 4. The index() method is used to find the index of the first occurrence of 'pineapple', which is 4.

v. Error handling for non-existing element:

    my_list = [1, 2, 3, 4, 5]
    try:
        index_6 = my_list.index(6)
        print("Index of the first occurrence of 6:", index_6)
    except ValueError:
        print("Element 6 not found in the list.")

# output:
Element 6 not found in the list.

Explain:

In the above example, the list my_list does not contain the element 6. When attempting to find the index of 6 using the index() method, a ValueError exception is raised. The except block catches this exception and prints a message indicating that element 6 is not found in the list.


copy() and list aliasing

copy() method and list aliasing is crucial for managing data effectively in Python, especially when dealing with mutable objects like lists. It helps prevent unintended side effects and ensures predictable behavior in your code.

Below are the 5 examples and explanations of the copy() method and list aliasing:

i. Using copy() to Clone a List

    original_list = [1, 2, 3, 4, 5]
    cloned_list = original_list.copy()
    print(cloned_list)

# output:
[1, 2, 3, 4, 5]

Explain:

  • In this example, copy() method is used to create a shallow copy of original_list and assign it to cloned_list.
  • Both original_list and cloned_list now contain the same elements [1, 2, 3, 4, 5].
  • This ensures that modifying one list does not affect the other.

ii. Basic Example: List Aliasing

    original_list = [1, 2, 3, 4, 5]
    aliased_list = original_list
    aliased_list.append(6)
    print(original_list)

#output:
[1, 2, 3, 4, 5, 6]

Explain:

  • Here, aliased_list is an alias (or reference) to original_list.
  • Modifying aliased_list also modifies original_list because they refer to the same object in memory.
  • Thus, original_list now contains [1, 2, 3, 4, 5, 6], reflecting the change made through aliased_list.

iii. Deep Copying Nested Lists

    import copy

    nested_list = [[1, 2], [3, 4]]
    deep_copy = copy.deepcopy(nested_list)
    deep_copy[0][0] = 100
    print(nested_list)

# output:
[[1, 2], [3, 4]]

Explain:

  • deepcopy() from the copy module creates a deep copy of a list, including all nested lists.
  • Modifying elements of deep_copy does not affect the corresponding elements in the nested_list.
  • In this example, changing deep_copy[0][0] to 100 doesn’t affect the original list, and nested_list remains [[1, 2], [3, 4]].

iv. Aliasing with List Comprehension

    original_list = [1, 2, 3, 4, 5]
    aliased_list = [item for item in original_list]
    aliased_list.append(6)
    print(original_list)

# output:
[1, 2, 3, 4, 5]

Explain:

  • List comprehension can also create an alias of the original list.
  • Here, aliased_list is a new list created using list comprehension, but it contains the same elements as original_list.
  • Thus, modifying aliased_list also modifies original_list.

v. Using list() Constructor for Shallow Copy

    original_list = [1, 2, 3, 4, 5]
    shallow_copy = list(original_list)
    shallow_copy.append(6)
    print(original_list)

# output:
[1, 2, 3, 4, 5]

Explain:

  • The list() constructor creates a shallow copy of the original list.
  • In this example, shallow_copy is a shallow copy of original_list.
  • Modifying shallow_copy does not affect original_list, as they are separate objects in memory.

Leave a Reply