Open In App

Python – Extract Preceding Record from list values

Sometimes, while working with Tuple records, we can have a problem in which we need to extract the record, which is preceding to particular key provided. This kind of problem can have application in domains such as web development and day-day programming. Let’s discuss certain ways in which this task can be performed.

Input : test_list = [(‘Gfg’, 3), (‘is’, 4), (‘best’, 1), (‘for’, 10), (‘geeks’, 11)], key = ‘geeks’ 
Output : (‘for’, 10)



Input : test_list = [(‘Gfg’, 3), (‘is’, 4), (‘best’, 1), (‘for’, 10), (‘geeks’, 11)], key = ‘is’ 
Output : (‘Gfg’, 3) 

Method #1 : Using zip() + enumerate() + loop 
The combination of above functions can be used to perform this particular task. In this, we create 2 lists, one with starting with next index. The zip(), helps to connect them and return the desired result using enumerate() for extracting index.






# Python3 code to demonstrate working of
# Extract Preceding Record
# Using zip() + enumerate() + loop
 
# initializing list
test_list = [('Gfg', 3), ('is', 4), ('best', 1), ('for', 10), ('geeks', 11)]
 
# printing original list
print("The original list is : " + str(test_list))
 
# initializing Key
key = 'for'
 
# Extract Preceding Record
# Using zip() + enumerate() + loop
for idx, (a, b) in enumerate(zip(test_list, test_list[1:])):
    if b[0] == key:
        res = (a[0], a[1])
 
# printing result
print("The Preceding record : " + str(res))

Output
The original list is : [('Gfg', 3), ('is', 4), ('best', 1), ('for', 10), ('geeks', 11)]
The Preceding record : ('best', 1)

Time Complexity: O(n) where n is the number of elements in the list as we are looping through the entire list once.
Auxiliary Space: O(1) as we are not using any extra space for storing the result, just a single variable.

Method #2 : Using list comprehension + enumerate() 
The combination of above functions can be used to solve this problem. In this, we perform the task of extracting the previous element to manually test previous key, rather than creating a separate list as in previous method.




# Python3 code to demonstrate working of
# Extract Preceding Record
# Using list comprehension + enumerate()
 
# initializing list
test_list = [('Gfg', 3), ('is', 4), ('best', 1), ('for', 10), ('geeks', 11)]
 
# printing original list
print("The original list is : " + str(test_list))
 
# initializing Key
key = 'for'
 
# Extract Preceding Record
# Using list comprehension + enumerate()
res = [(test_list[idx - 1][0], test_list[idx - 1][1])
      for idx, (x, y) in enumerate(test_list) if x == key and idx > 0]
 
# printing result
print("The Preceding record : " + str(res))

Output
The original list is : [('Gfg', 3), ('is', 4), ('best', 1), ('for', 10), ('geeks', 11)]
The Preceding record : [('best', 1)]

Time complexity: O(n) because it iterates through the input list once to find the preceding record.
Auxiliary space: O(1), as it only uses a fixed amount of memory for storing the input list, key, and output list. The list comprehension used to generate the output list doesn’t create any additional lists or variables, so the space complexity remains constant regardless of the size of the input list.

Method #3 : Using for loop




# Python3 code to demonstrate working of
# Extract Preceding Record
 
# initializing list
test_list = [('Gfg', 3), ('is', 4), ('best', 1), ('for', 10), ('geeks', 11)]
 
# printing original list
print("The original list is : " + str(test_list))
 
# initializing Key
key = 'for'
 
# Extract Preceding Record
 
for i in range(0,len(test_list)):
    if key in test_list[i]:
        idx=i
        break
res=test_list[idx-1]
# printing result
print("The Preceding record : " + str(res))

Output
The original list is : [('Gfg', 3), ('is', 4), ('best', 1), ('for', 10), ('geeks', 11)]
The Preceding record : ('best', 1)

Time Complexity: O(n) where n is the number of elements in the list “test_list”.  for loop performs n number of operations.
Auxiliary Space: O(1), constant extra space is required 

Method 3: Using enumerate() and a loop:

Step-by-step approach:

Below is the implementation of the above approach:




test_list = [('Gfg', 3), ('is', 4), ('best', 1), ('for', 10), ('geeks', 11)]
key = 'for'
 
# Using enumerate() + loop
for i, (a, b) in enumerate(zip(test_list, test_list[1:])):
    if b[0] == key:
        res = a
        break
 
print("The Preceding record : " + str(res))

Output
The Preceding record : ('best', 1)

Time Complexity: O(n) where n is the number of elements in the list “test_list”. 
Auxiliary Space: O(1), constant extra space is required 

Method #6: Using a dictionary to store the values and their indices

First initialize an empty dictionary and iterate through the original list to store the values and their indices in the dictionary. Then, check if the given key is present in the dictionary. If it is present, retrieve its index and check if it is greater than 0. If it is greater than 0, retrieve the element at index-1 as the preceding record. If it is not greater than 0, set the result to None. Finally, print the result.

Step-by-step approach:

Below is the implementation of the above approach:




# Python3 code to demonstrate working of
# Extract Preceding Record
# Using a dictionary to store the values and their indices
 
# initializing list
test_list = [('Gfg', 3), ('is', 4), ('best', 1), ('for', 10), ('geeks', 11)]
 
# printing original list
print("The original list is : " + str(test_list))
 
# initializing Key
key = 'for'
 
# Using a dictionary to store the values and their indices
dictionary = {}
for idx, (a, b) in enumerate(test_list):
    dictionary[a] = idx
 
if key in dictionary:
    index = dictionary[key]
    if index > 0:
        res = test_list[index-1]
    else:
        res = None
 
# printing result
print("The Preceding record : " + str(res))

Output
The original list is : [('Gfg', 3), ('is', 4), ('best', 1), ('for', 10), ('geeks', 11)]
The Preceding record : ('best', 1)

Time Complexity: O(n), where n is the length of the original list.
Auxiliary Space: O(n), where n is the length of the original list, as we are storing the values and their indices in a dictionary.

Method #7: Using itertools.groupby()




# Python3 code to demonstrate working of
# Extract Preceding Record
# Using itertools.groupby()
 
from itertools import groupby
 
# initializing list
test_list = [('Gfg', 3), ('is', 4), ('best', 1), ('for', 10), ('geeks', 11)]
 
# printing original list
print("The original list is : " + str(test_list))
 
# initializing Key
key = 'for'
 
# Extract Preceding Record
# Using itertools.groupby()
groups = groupby(test_list, lambda x: x[0] != key)
preceding_group = list(next(groups)[1])
res = preceding_group[-1]
 
# printing result
print("The Preceding record : " + str(res))

Output
The original list is : [('Gfg', 3), ('is', 4), ('best', 1), ('for', 10), ('geeks', 11)]
The Preceding record : ('best', 1)

Time complexity: O(n), where n is the length of the input list. This is because we are iterating over the input list once.

Auxiliary space: O(1), because we are not using any extra data structures.

Method #8: Using numpy:

  1. Initialize the list of tuples.
  2. Initialize the key to be searched in the list.
  3. Initialize an empty dictionary.
  4. Traverse the list of tuples using a for loop with an enumerate function, which assigns an index to each tuple.
  5. Store the key of each tuple as a key and its corresponding index as a value in the dictionary.
  6. Check if the key exists in the dictionary.
  7. If the key exists, get the index of the key in the list using the dictionary.
  8. Check if the index is greater than 0.
  9. If the index is greater than 0, get the tuple at the index – 1 in the list.
  10. If the index is 0, assign None to the result.
  11. Print the preceding record.




import numpy as np
 
# initializing list
test_list = [('Gfg', 3), ('is', 4), ('best', 1), ('for', 10), ('geeks', 11)]
 
# printing original list
print("The original list is : " + str(test_list))
 
# initializing key
key = 'for'
 
# convert list of tuples to NumPy array
arr = np.array(test_list)
 
# get index of key in the array
idx = np.where(arr[:,0] == key)[0]
 
# if key is found and has a preceding record, return it
if len(idx) > 0 and idx > 0:
    res = arr[idx-1]
else:
    res = None
 
# print result
print("The preceding record: " + str(res))
#This code is contributed by Jyothi pinjala.

Output:

The original list is : [(‘Gfg’, 3), (‘is’, 4), (‘best’, 1), (‘for’, 10), (‘geeks’, 11)]
The preceding record: [[‘best’ ‘1’]]
 

Time complexity:
The time complexity is O(n), where n is the number of elements in the list. Converting the list to a NumPy array using the np.array() function takes O(n) time, and searching for the index of the key in the array using the np.where() function takes O(n) time in the worst case. Extracting the preceding record from the array takes O(1) time.

Space complexity:
The space complexity  is O(n), where n is the number of elements in the list. This is because we need to store the list in a NumPy array, which has the same length as the list. We also need to store the indices of the elements in the array that are equal to the key, which has a maximum length of n. The space complexity of the other variables and the returned result is not included in the analysis.


Article Tags :