Python | Check if Non-None values are contiguous
Last Updated :
02 Jun, 2023
Sometimes, while working with Python lists, we can have a problem in which we need to find if all the values that are valid (Non None). This has a lot of application in day-day programming. Let’s discuss a method in which this task can be performed.
Method 1: Using iterator + all() + any() Combination of above functions can be used to perform this particular task. In this, we filter the leading None values using initial all(), then check for singular valid value sublist using any(), and then check for all the required None values. If any of the above return false. The Non-None values are not contiguous.
Python3
def check_cont(test_list):
test_list = iter (test_list)
all (x is None for x in test_list)
any (x is None for x in test_list)
return all (x is None for x in test_list)
test_list = [ None , None , 'Gfg' , 'is' , 'Good' , None , None , None ]
print ( "The original list : " + str (test_list))
res = check_cont(test_list)
print ( "Are non-none values contiguous ? : " + str (res))
|
Output
The original list : [None, None, 'Gfg', 'is', 'Good', None, None, None]
Are non-none values contiguous ? : True
Time Complexity: O(n) where n is the number of elements in the list “test_list”. iterator + all() + any() performs n number of operations.
Auxiliary Space: O(1), constant extra space is required
Method 2: Using min(),max() and index() methods
Python3
test_list = [ None , None , 'Gfg' , 'is' , 'Good' , None , None , None ]
print ( "The original list : " + str (test_list))
res = []
for i in test_list:
if i is not None :
res.append(test_list.index(i))
mi = min (res)
ma = max (res)
x = []
for i in range (mi,ma + 1 ):
x.append(i)
res1 = False
if (x = = res):
res1 = True
print ( "Are non-none values contiguous ? : " + str (res1))
|
Output
The original list : [None, None, 'Gfg', 'is', 'Good', None, None, None]
Are non-none values contiguous ? : True
Method #3: Using Listcomprehension
- Define the check_cont() function that takes a list as input.
- Use a list comprehension to create a new list containing the indices of all non-None values in the input list.
- Use the zip() function to create pairs of adjacent indices in the new list.
- Use the all() function to check if the difference between each pair of adjacent indices is 1.
- Return the result of the all() function.
- Create a test list with some None and non-None values.
- Call the check_cont() function with the test list as input.
- Print the result of the function.
Python3
def check_cont(test_list):
non_none = [i for i, x in enumerate (test_list) if x is not None ]
return all (j - i = = 1 for i, j in zip (non_none, non_none[ 1 :]))
test_list = [ None , None , 'Gfg' , 'is' , 'Good' , None , None , None ]
res = check_cont(test_list)
print ( "Are non-none values contiguous? : " + str (res))
|
Output
Are non-none values contiguous? : True
Time complexity: The list comprehension takes O(n) time to create a new list containing the indices of all non-None values in the input list. The zip() function and the all() function both iterate over this new list, which takes O(n) time. Therefore, the overall time complexity of this function is O(n).
Space complexity: The list comprehension creates a new list containing the indices of all non-None values in the input list, which takes O(k) space where k is the number of non-None values in the input list. The zip() function and the all() function both iterate over this new list, so they do not use any additional space. Therefore, the overall space complexity of this function is O(k).
Method#4:Using list slicing and the count() function
- Count the number of None values in the input list.
- If the count of None values is 0, return True, as all values are contiguous.
- If the count of None values is 1, return False, as there is only one non-None value and it cannot be considered contiguous
- Find the index of the first non-None value in the list.
- Find the index of the last non-None value in the list.
- Extract a slice of the list between the indices of the first and last non-None values.
- Count the number of None values in the extracted slice.
- If the count of None values in the slice is 0, return True, as all non-None values are contiguous. Otherwise, return False.
Python3
def check_cont(test_list):
non_none_count = test_list.count( None )
if non_none_count = = 0 :
return True
if non_none_count = = 1 :
return False
start_index = test_list.index( next (val for val in test_list if val is not None ))
end_index = len (test_list) - test_list[:: - 1 ].index( next (val for val in test_list[:: - 1 ] if val is not None )) - 1
return test_list[start_index:end_index + 1 ].count( None ) = = 0
test_list = [ None , None , 'Gfg' , 'is' , 'Good' , None , None , None ]
print ( "The original list : " + str (test_list))
res = check_cont(test_list)
print ( "Are non-None values contiguous? : " + str (res))
|
Output
The original list : [None, None, 'Gfg', 'is', 'Good', None, None, None]
Are non-None values contiguous? : True
The time complexity of this approach is O(n), where n is the length of the input list. This is because we need to iterate over the list to count the number of None values, find the indices of the first and last non-None values, and extract the slice of the list between those indices.
The auxiliary space complexity of this approach is O(1), as we are not using any additional data structures that scale with the size of the input.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...