Open In App
Related Articles

Python | Prefix Sum Subarray till False value

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Report issue
Report

The prefix array is quite famous in the programming practice. This article would discuss a variation of this scheme. This deals with the cumulative list sum till a False value, and again starts cumulation from the occurrence of True value. Let’s discuss certain ways in which this can be performed. 

Method #1 : Using Naive Method In the naive method, we just construct the new list comprising of the summation of prev. value of list until 0 and restarts the procedure once a non-zero value is encountered. 
 

Python3

# Python3 code to demonstrate
# Prefix Sum Subarray till False value
# using naive method
 
# initializing list of lists
test_list = [1, 3, 4, 0, 4, 5, 0, 7, 8]
 
# printing original list
print ("The original list is : " + str(test_list))
 
# Prefix Sum Subarray till False value
# using naive method
for i in range(1, len(test_list)):
    if test_list[i]: 
        test_list[i] += test_list[i - 1]
 
# printing result
print ("The computed modified new list : " + str(test_list))

                    
Output:
The original list is : [1, 3, 4, 0, 4, 5, 0, 7, 8]
The computed modified new list : [1, 4, 8, 0, 4, 9, 0, 7, 15]

Time Complexity: O(n), where n is the length of the list test_list 
Auxiliary Space: O(n) additional space of size n is created where n is the number of elements in the res list 

  Method #2 : Using from_iterable() + accumulate() + groupby() The above three functions combine together to perform this particular task. In this, the accumulate function performs the task of addition of elements, groupby function groups the non-zero values and the result is combined by the from_iterable function. 

Python3

# Python3 code to demonstrate
# Prefix Sum Subarray till False value
# from_iterable() + accumulate() + groupby()
from itertools import groupby, accumulate, chain
 
# initializing list of lists
test_list = [1, 3, 4, 0, 4, 5, 0, 7, 8]
 
# printing original list
print ("The original list is : " + str(test_list))
 
# Prefix Sum Subarray till False value
# from_iterable() + accumulate() + groupby()
res = list(chain.from_iterable(accumulate(j)
            for i, j in groupby(test_list, bool)))
 
# printing result
print ("The computed modified new list : " + str(res))

                    
Output:
The original list is : [1, 3, 4, 0, 4, 5, 0, 7, 8]
The computed modified new list : [1, 4, 8, 0, 4, 9, 0, 7, 15]

Method #3: Using list comprehension

Algorithm:

  1. Initialize the input list test_list.
  2. Print the original list.
  3. Compute the modified list using list comprehension:
  4. For each element test_list[i] starting from index 1 up to the end of the list, if the element is True (i.e., non zero), add the value of the previous element test_list[i-1] to the current element test_list[i]. Otherwise, leave the element unchanged.
  5. Print the computed modified list.

Python3

# initializing list of lists
test_list = [1, 3, 4, 0, 4, 5, 0, 7, 8]
 
# printing original list
print("The original list is : " + str(test_list))
 
# Prefix Sum Subarray till False value using list comprehension
test_list = [test_list[i] + test_list[i-1] if test_list[i] else test_list[i] for i in range(1, len(test_list))]
 
# printing result
print("The computed modified new list : " + str(test_list))
#This code is contributed by Vinay Pinjala.

                    

Output
The original list is : [1, 3, 4, 0, 4, 5, 0, 7, 8]
The computed modified new list : [4, 7, 0, 4, 9, 0, 7, 15]

The time complexity of this algorithm is O(N), where N is the length of the input list test_list. This is because we iterate through each element in the list once to compute the modified list using list comprehension.
Space Complexity:

The auxiliary space of this algorithm is O(N), where N is the length of the input list test_list. This is because we create a new list to store the modified list, which has the same length as the input list. Note that the space complexity could be reduced to O(1) by modifying the input list in place instead of creating a new list, but this would change the original input list.

Method 4: Using map function with lambda expression.

Algorithm:

  1. Create a new list prefix_sum and initialize it with the first element as 0, and the remaining elements as the original list.
  2. Apply map function on a lambda function to iterate over the range 1 to length of prefix_sum.
  3. For each iteration, check if the current element is not equal to 0, then add the previous element of prefix_sum to the current element of prefix_sum and update it in the test_list.
  4. Return the modified test_list by slicing from the second element to the end of the list.

Python3

test_list = [1, 3, 4, 0, 4, 5, 0, 7, 8]
prefix_sum = [0] + test_list
print("The original list is : " + str(test_list))
 
test_list = list(map(lambda i: prefix_sum[i] + prefix_sum[i-1] if prefix_sum[i] else prefix_sum[i], range(1, len(prefix_sum))))
print("The computed modified new list : " + str(test_list[1:]))

                    

Output
The original list is : [1, 3, 4, 0, 4, 5, 0, 7, 8]
The computed modified new list : [4, 7, 0, 4, 9, 0, 7, 15]

Time Complexity: O(n)

The time complexity of creating prefix_sum list and map function is O(n).
The lambda function executes n-1 times, so its time complexity is O(1) for each execution.
Therefore, the overall time complexity is O(n).
Auxiliary Space: O(n) We use an additional prefix_sum list, which has the same size as the original list.
Therefore, the space complexity is O(n).

Method 5: Using heapq:

Algorithm:

  1. Initialize a heap with a tuple (0, -1), where 0 is the prefix sum of the subarray ending at index -1.
  2. Initialize a list res with zeros of the same length as test_list.
  3. Traverse the list test_list with index i and value x.
  4. If x is non-zero, pop the smallest element (s, j) from the heap and set res[i] to s + x. Push (s + x, j) back to the heap.
  5. If x is zero, push (0, i) to the heap.
  6. The list res is the computed modified new list.

Python3

import heapq
 
# initializing list of lists
test_list = [1, 3, 4, 0, 4, 5, 0, 7, 8]
 
# printing original list
print("The original list is : " + str(test_list))
 
# Prefix Sum Subarray till False value using heapq method
heap = [(0, -1)]
res = [0] * len(test_list)
 
for i, x in enumerate(test_list):
    if x:
        s, j = heapq.heappop(heap)
        res[i] = s + x
        heapq.heappush(heap, (s + x, j))
    else:
        heapq.heappush(heap, (0, i))
 
# printing result
print("The computed modified new list using heapq method: " + str(res))
#This code is contributed by Jyothi pinjala.

                    

Output
The original list is : [1, 3, 4, 0, 4, 5, 0, 7, 8]
The computed modified new list using heapq method: [1, 4, 8, 0, 4, 9, 0, 7, 15]

Time complexity:
The time complexity of the algorithm is O(n*log n), where n is the length of the input list test_list. The loop traverses the input list once, and for each non-zero value, a heap operation is performed which takes O(log n) time.

Space complexity:
The space complexity of the algorithm is O(n), where n is the length of the input list test_list. The heap can contain at most n elements, and the list res has length n.



Last Updated : 03 May, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads