# Python | Valid Ranges Product

Last Updated : 10 Apr, 2023

Many times we need to get the product of not the whole list but just a part of it and at regular intervals. These intervals are sometimes decided statically before traversal, but sometimes, the constraint is more dynamic and hence we require to handle it in more complex way. Criteria discussed here is product of non-zero groups. Letâ€™s discuss certain ways in which this task can be done.

Method #1 : Using loops This task can be performed using the brute force manner using the loops. We just traverse the list each element to test for itâ€™s succeeding element to be non-zero value and perform the product once we find a next value to be zero and append it in result list.

## Python3

 `# Python3 code to demonstrate` `# Valid Ranges Product` `# Using loops`   `# initializing list` `test_list ``=` `[``4``, ``9``, ``0``, ``0``, ``3``, ``4``, ``5``, ``0``, ``0``, ``4``, ``0``]`   `# printing original list` `print``("The original ``list` `: " ``+` `str``(test_list))`   `# using loops` `# Valid Ranges Product` `res ``=` `[]` `val ``=` `1` `for` `ele ``in` `test_list:` `    ``if` `ele ``=``=` `0``:` `        ``if` `val !``=` `1``:` `            ``res.append(val)` `            ``val ``=` `1` `    ``else``:` `        ``val ``*``=` `ele`   `# print result` `print``("The non``-``zero group product of ``list` `is` `: " ``+` `str``(res))`

Output :

```The original list : [4, 9, 0, 0, 3, 4, 5, 0, 0, 4, 0]
The non-zero group product of list is : [36, 60, 4]```

Time complexity: O(n), where n is the length of the test_list. The loop  takes O(n) time
Auxiliary Space: O(n), extra space of size n is required

Method #2 : Using itertools.groupby() + loop This particular task can also be performed using groupby function to group all the non-zero values and product can be performed using loop.

## Python3

 `# Python3 code to demonstrate` `# Valid Ranges Product` `# Using itertools.groupby() + loop` `from` `itertools ``import` `groupby`   `# getting Product` `def` `prod(val) :` `    ``res ``=` `1` `    ``for` `ele ``in` `val:` `        ``res ``*``=` `ele` `    ``return` `res ` `    `  `# initializing list` `test_list ``=` `[``4``, ``9``, ``0``, ``0``, ``3``, ``4``, ``5``, ``0``, ``0``, ``4``, ``0``]`   `# printing original list` `print``("The original ``list` `: " ``+` `str``(test_list))`   `# using itertools.groupby() + loop` `# Valid Ranges Product` `res ``=` `[prod(val) ``for` `keys, val ``in` `groupby(test_list, key ``=` `lambda` `x: x !``=` `0``) ``if` `keys !``=` `0``]`   `# print result` `print``("The non``-``zero group product of ``list` `is` `: " ``+` `str``(res))`

Output :

```The original list : [4, 9, 0, 0, 3, 4, 5, 0, 0, 4, 0]
The non-zero group product of list is : [36, 60, 4]```

Time Complexity: O(n*n), where n is the length of the input list. This is because weâ€™re using itertools.groupby() + loop which has a time complexity of O(n*n) in the worst case.
Auxiliary Space: O(n), as weâ€™re using additional space res other than the input list itself with the same size of input list

#### Method #3 : Using list + while loops

In this solution, we first define the original list lst. We then iterate through the list using a for loop and keep track of the start index start of each non-zero group. If we encounter a zero, we check if there is a non-zero group currently being tracked (i.e., if start is not equal to -1). If there is, we compute the product of the non-zero group using the math.prod() function and add it to the products list. We then reset the start index to -1 to indicate that we are not currently tracking a non-zero group. If we encounter a non-zero element, we update the start index if necessary (i.e., if it is currently -1). After iterating through the entire list, we check if there is a non-zero group at the end of the list. If there is, we compute its product and add it to the products list. Finally, we print the products list, which contains the non-zero group product of lst.

## Python

 `# Define the original list` `lst ``=` `[``4``, ``9``, ``0``, ``0``, ``3``, ``4``, ``5``, ``0``, ``0``, ``4``, ``0``]`   `# Initialize variables` `products ``=` `[]` `start ``=` `0`   `# Iterate through the list using a while loop` `while` `start < ``len``(lst):` `    ``# Find the next non-zero element` `    ``while` `start < ``len``(lst) ``and` `lst[start] ``=``=` `0``:` `        ``start ``+``=` `1` `    `  `    ``# If there are no more non-zero elements, break out of the loop` `    ``if` `start ``=``=` `len``(lst):` `        ``break` `    `  `    ``# Compute the product of the current non-zero group` `    ``product ``=` `lst[start]` `    ``i ``=` `start ``+` `1` `    ``while` `i < ``len``(lst) ``and` `lst[i] !``=` `0``:` `        ``product ``*``=` `lst[i]` `        ``i ``+``=` `1` `    `  `    ``# Add the product to the list of products` `    ``products.append(product)` `    `  `    ``# Update the start index` `    ``start ``=` `i`   `# Print the result` `print``(``"The non-zero group product of list is :"``, products)`

Output

`('The non-zero group product of list is :', [36, 60, 4])`

Time complexity: O(n)
Auxiliary Space: O(m)

Method #4 :Using list comprehension and reduce():

1. Initialize an empty list called res to store the non-zero group products.
2. Use zip() to create two lists: one that contains the starting index of each non-zero group (including the first element at index 0), and one that 3. contains the ending index of each non-zero group (including the last element at index len(test_list)). These lists can be created using list comprehension.
4. For each non-zero group of the list:
5. Use reduce() to calculate the product of the elements in that group.
6. If the resulting product is not zero, append it to the res list.
7. Print the res list as a string using the str() function.

## Python3

 `from` `functools ``import` `reduce`   `# Define the input list` `test_list ``=` `[``4``, ``9``, ``0``, ``0``, ``3``, ``4``, ``5``, ``0``, ``0``, ``4``, ``0``]` `# printing original list` `print``(``"The original list : "` `+` `str``(test_list))` ` `    `# Initialize the result list` `res ``=` `[]`   `# Use zip() to create two lists: one with the starting index of each non-zero group,` `# and one with the ending index of each non-zero group` `start_idx ``=` `[``0``] ``+` `[j ``+` `1` `for` `j ``in` `range``(``len``(test_list)) ``if` `test_list[j] ``=``=` `0``]` `end_idx ``=` `[j ``for` `j ``in` `range``(``len``(test_list)) ``if` `test_list[j] ``=``=` `0``] ``+` `[``len``(test_list)]`   `# For each non-zero group, calculate the product of the elements and append it to the result list` `for` `i, j ``in` `zip``(start_idx, end_idx):` `    ``if` `not` `all``(num ``=``=` `0` `for` `num ``in` `test_list[i:j]):` `        ``product ``=` `reduce``(``lambda` `x, y: x ``*` `y, test_list[i:j])` `        ``res.append(product)`   `# Print the result list as a string` `print``(``"The non-zero group product of list is : "` `+` `str``(res))`   `#This code is contributed by Jyothi pinjala.`

Output

```The original list : [4, 9, 0, 0, 3, 4, 5, 0, 0, 4, 0]
The non-zero group product of list is : [36, 60, 4]```

The time complexity: O(n), where n is the length of the input list test_list. This is because the algorithm iterates through the list once to create the start_idx and end_idx lists, and then iterates through each non-zero group of the list once to calculate its product using reduce().

The space complexity: O(n), because the start_idx, end_idx, and res lists all have at most n elements. Note that the reduce() function uses O(1) space to store intermediate products.