I can find max value, I can find average but I just can't seem to find the min. I know there is a way to find max and min in a loop but right now I can only find the max.
def large(s)
sum=0
n=0
for number in s:
if number>n:
n=number
return n
Is there a way to find the min value using this function?
You can use Python's built-in sum(), min(), and max() functions for this kind of analysis.
However, if you're wanting to do it all in one pass or just want to learn how to write it yourself, then the process is 1) iterate over the input and 2) keep track of the cumulative sum, the minimum value seen so far, and the maximum value seen so far:
def stats(iterable):
'''Return a tuple of the minimum, average, and maximum values
>>> stats([20, 50, 30, 40])
(20, 35.0, 50)
'''
it = iter(iterable)
first = next(it) # Raises an exception if the input is empty
minimum = maximum = cumsum = first
n = 1
for x in it:
n += 1
cumsum += x
if x < minimum:
minimum = x
if x > maximum:
maximum = x
average = cumsum / float(n)
return minimum, average, maximum
if __name__ == '__main__':
import doctest
print doctest.testmod()
The code has one other nuance. It uses the first value from the input iterable as the starting value for the minimum, maximum, and cumulative sum. This is preferred over creating a positive or negative infinity value as initial values for the maximum and minimum. FWIW, Python's own builtin functions are written this way.
Finding the minimum takes the same algorithm as finding the maximum, but with the comparison reversed. < becomes > and vice versa. Initialize the minimum to the largest value possible, which is float("inf"), or to the first element of the list.
FYI, Python has a builtin min function for this purpose.
You must set n to a very high number (higher than any of the expected) or to take one from the list to start comparison:
def large(s)
n = s.pop()
for number in s:
if number < n:
n = number
return n
Obviously you have already max and min for this purpose.
A straightforward solution:
def minimum(lst):
n = float('+inf')
for num in lst:
if num < n:
n = num
return n
Explanation: first, you initialize n (the minimum number) to a very large value, in such a way that any other number will be smaller than it - for example, the infinite value. It's an initialization trick, in case the list is empty, it will return infinite, meaning with that that the list was empty and it didn't contain a minimum value.
After that, we iterate over all the values in the list, checking each one to see if it is smaller than the value we assumed to be the minimum. If a new minimum is found, we update the value of n.
At the end, we return the minimum value found.
Why not just replace large with small and > with <? Also, you might not want to initialize n to 0 if you're looking for the smallest value. Your large function only works for lists of positive numbers. Also, you're missing a ":" after your def line.
def small(s):
if len(s)==0: return None
n = s[0]
for number in s[1:]:
if n < number:
n=number
return n
This handles empty lists by returning None.
Using this function to find minimum is
min=-large(-s)
The logic is just to find maximum of the negative list , which gives the minimum value
You can use same function with iteration just instead of n=0 use n=L[0]
def min(L):
n=L[0]
for x in L:
if x
def min(s):
n=s[0]
for number in s:
if number < n:
n=number
return n
Related
This function finds the maximum and minimum values.
n=int(input())
array=list(map(int,input().split))
for i in range(n):
max=array[0]
if i>0:
if max<array[i]:
max=array[i]
for i in range(n):
min=array[0]
if i>0:
if min>array[i]:
min=array[i]
print(max,end='')
print( min)
The maximum value comes out normally, but the minimum value comes out as the first array value. I can't find what is wrong.
The maximum value comes out normally
I think it does only because either your first or last value is the max of the sequence. Because you completely reset both min and max on each iteration. So the entire loop is useless, any iteration but the last has no effect.
The initialisation should be outside the loop, not inside of it:
max=array[0]
for i in range(n):
if i>0:
if max<array[i]:
max=array[i]
min=array[0]
for i in range(n):
if i>0:
if min>array[i]:
min=array[i]
At which point the check on the index is clearly unnecessary: either eat the unnecessary comparison of array[0] to array[0] (it's not harmful per-se), or just skip the index when iterating:
max=array[0]
for i in range(1, n):
if max<array[i]:
max=array[i]
min=array[0]
for i in range(1, n):
if min>array[i]:
min=array[i]
In essence you've written a very complicated version of:
if array[0] < array[-1]:
max = array[-1]
else:
max = array[0]
if array[0] > array[-1]:
min = array[-1]
else:
min = array[0]
Now for further improvements, under the assumption that you're trying to learn we'll ignore that min and max are already built-in functions and thus the entire thing is redundant (although you should not name your own variables the same as builtins, as that creates confusion):
n is useless, because it's not checked against array and array has its own length, n can only trigger unnecessary errors if it exceeds len(array), or skip item if it's smaller than len(array). n might be useful if e.g. the input was gathered in a loop of validated input() call, which is not the case.
Good error handling would probably check that the length of the array is at least 1, otherwise the script will blow up (although it would also need to check that individual input values are valid before converting to integers so...)
You can extract min and max in the same loop, no need to loop twice (probably not very important in this case).
But Python also has good support for iterators, so you should avoid explicit indexing when not necessary, which it is not here.
And my take, still within the realm of trying to learn, would be:
array=list(map(int,input().split))
low = high = array[0]
for candidate in array[1:]:
if candidate > high:
high = candidate
if candidate < low:
low = candidate
print(f"{low} ... {high}")
An other fun alternative is to sort the array and take the first and last elements of the now-sorted array:
array=list(map(int,input().split))
low, *_, high = sorted(array)
print(f"{low} ... {high}")
although it has the drawback that it only works on array of length 2+ where the original works on "singleton" arrays.
Use the min and max keyword from python for this.
E.g.
my_list = [0, -5, 3, 1, 10]
min_value = min(my_list)
max_value = max(my_list)
print(f'Min value: {min_value}, max value: {max_value}')
Do you just want the min and max of a list of integers a user inputs? Use the build-in functions of python for that:
list_of_user_input = []
n_input = int(input("How many variables do you want to enter: "))
for i in range(0, n_input):
number = int(input(f"Enter variable {i + 1}: "))
list_of_user_input.append(number)
print(f"The min of your list is {min(list_of_user_input)}")
print(f"The max of your list is {max(list_of_user_input)}")
Hi I have a problem with my code and I don't know how to solve it. The challenge is :"How many consecutive numbers are needed?" ... to fill an array. Example: [1, 2, 4, 6] the answer should be 2.
This is what I got.
def consecutive(arr):
arr.sort()
minimum = min(arr)
maximum = max(arr)
diff = maximum - minimum - len(arr) + 1
return diff
the proble is when arr is [] then it doesnt work. What can I change about my code.
You can only compute the minimum and maximum of a non-empty list, so you have two alternatives: raise an exception if the input is empty, or provide a default value to return in the case of an empty list. (Both cases defer to the caller to decide what is needed if the list is empty, rather than forcing the function to guess at an appropriate value.)
Raise an exception.
def consecutive(arr):
if not arr:
raise ValueError("List is empty")
minimum = min(arr)
maximum = max(arr)
diff = maximum - minimum - len(arr) + 1
return diff
Provide a default
def consecutive(arr, if_empty=None):
if not arr:
return if_empty
minimum = min(arr)
maximum = max(arr)
diff = maximum - minimum - len(arr) + 1
return diff
Note that in neither case do you have to sort the list first; both min and max handle unsorted lists just fine.
Maybe I am reading too much into the question, but the answers provided so far, as well as the OP's own answer, are wrong if arr has repeated elements such as [1,2,2,6]. So the correct answer, 'borrowing'' error handling code from #chepner, is
def consecutive(arr):
if not arr:
raise ValueError("List is empty")
minimum = min(arr)
maximum = max(arr)
diff = maximum - minimum - len(set(arr)) + 1
return diff
Here set(arr) returns unique elements of arr
I am attempting to find the indices of the two smallest and the two largest values in python:
I have
import sklearn
euclidean_matrix=sklearn.metrics.pairwise_distances(H10.T,metric='euclidean')
max_index =np.where(euclidean_matrix==np.max(euclidean_matrix[np.nonzero(euclidean_matrix)]))
min_index=np.where(euclidean_matrix==np.min(euclidean_matrix[np.nonzero(euclidean_matrix)]))
min_index
max_index
I get the following output
(array([158, 272]), array([272, 158]))
(array([ 31, 150]), array([150, 31]))
the above code only returns the indices of the absolute smallest and the absolute largest values of the matrix, I would like to find the indices of the next smallest value and the indices of the next largest value. How can I do this? Ideally I would like to return the indices of the 2 largest values of the matrix and the indices of the two smallest values of the matrix. How can I do this?
I can think of a couple ways of doing this. Some of these depend on how much data you need to search through.
A couple of caveats: You will have to decide what to do when there are 1, 2, 3 elements only Or if all the same value, do you want min, max, etc to be identical? What if there are multiple items in max or min or min2, max2? which should be selected?
run min then remove that element run min on the rest. run max then remove that element and run on the rest (note that this is on the original and not the one with min removed). This is the least efficient method since it requires searching 4 times and copying twice. (Actually 8 times because we find the min/max then find the index.) Something like the in the pseudo code.
PSEUDO CODE:
max_index = np.where(euclidean_matrix==np.max(euclidean_matrix[np.nonzero(euclidean_matrix)]))
tmp_euclidean_matrix = euclidean_matrix #make sure this is a deepcopy
tmp_euclidean_matrix.remove(max_index) #syntax might not be right?
max_index2 = np.where(tmp_euclidean_matrix==np.max(tmp_euclidean_matrix[np.nonzero(tmp_euclidean_matrix)]))
min_index = np.where(euclidean_matrix==np.min(euclidean_matrix[np.nonzero(euclidean_matrix)]))
tmp_euclidean_matrix = euclidean_matrix #make sure this is a deepcopy
tmp_euclidean_matrix.remove(min_index) #syntax might not be right?
min_index2 = np.where(tmp_euclidean_matrix==np.min(tmp_euclidean_matrix[np.nonzero(tmp_euclidean_matrix)]))
Sort the data (if you need it sorted anyway this is a good option) then just grab two smallest and largest. This isn't great unless you needed it sorted anyway because of many copies and comparisons to sort.
PSEUDO CODE:
euclidean_matrix.sort()
min_index = 0
min_index2 = 1
max_index = len(euclidean_matrix) - 1
max_index2 = max_index - 1
Best option would be to roll your own search function to run on the data, this would be most efficient because you would go through the data only once to collect them.
This is just a simple iterative approach, other algorithms may be more efficient. You will want to validate this works though.
PSEUDO CODE:
def minmax2(array):
""" returns (minimum, second minimum, second maximum, maximum)
"""
if len(array) == 0:
raise Exception('Empty List')
elif len(array) == 1:
#special case only 1 element need at least 2 to have different
minimum = 0
minimum2 = 0
maximum2 = 0
maximum = 0
else:
minimum = 0
minimum2 = 1
maximum2 = 1
maximum = 0
for i in range(1, len(array)):
if array[i] <= array[minimum]:
# a new minimum (or tie) will shift the other minimum
minimum2 = minimum
minimum = i
elif array[i] < array[minimum2]:
minimum2 = i
elif array[i] >= array[maximum]:
# a new maximum (or tie) will shift the second maximum
maximum2 = maximum
maximum = i
elif array[i] > array[maximum2]:
maximum2 = i
return (minimum, minimum2, maximum2, maximum)
edit: Added pseudo code
Given an array of integers, and a number ‘sum’, find the number of pairs of integers in the array whose sum is equal to given ‘sum’ in a SINGLE iteration. (O(n) Time complexity is not enough!).
Usually, I would iterate twice through the array once to create hashmap of frequencies and another to find the number of pairs as shown below
def getPairsCount(arr, n, sum):
m=defaultdict(int)
for i in range(0, n): #iteration NO. 1
m[arr[i]] += 1
twice_count = 0
for i in range(0, n): #iteration NO. 2
twice_count += m[sum - arr[i]]
if (sum - arr[i] == arr[i]):
twice_count -= 1
return int(twice_count / 2)
I was asked to do the same in a single iteration instead of two by an interviewer. I am at loss how to do it wihout breaking it at edge cases like {2,2,1,1} where required sum is 3.
A way is to build the hash map at the same time as you are consuming it (thereby only looping the list once). Thus, for each value in the array, check if you have seen the complement (the value needed for the sum) before. If so, you know you have a new pair, and you remove the complement from the seen values. Otherwise you do not have a sum and you add the value you have just seen.
In code this looks like follows:
from collections import defaultdict
def get_pairs_count(array, sum):
pairs_count = 0
seen_values = defaultdict(int)
for value in array:
complement = sum - value
if seen_values[complement] > 0:
pairs_count += 1
seen_values[complement] -= 1
else:
seen_values[value] += 1
return pairs_count
Another way:
def pair_sum2(arr, k):
if len(arr)<2:
return
seen=set()
output=set()
for num in arr:
target=k-num
print("target",target)
if target not in seen:
print("seen before add",seen)
seen.add(num)
print("seen",seen)
else:
output.add( (min(num, target), max(num, target)) )
print("op:",output)
print ('\n'.join( map(str, list(output)) ) )
So basically I need a function that calculates the difference between each value in a list then tests against the threshold. If the difference between two adjacent numbers are greater than the given threshold, then the average between the two numbers should be inserted into the list sequentially. If the difference is not larger than it should return the original list. Only one number at the max should be inserted.
I have
def test(list, Threshold):
for i in range(len(list)):
if abs((list[i] - list[i+1])) > Threshold :
((list[i] + list[i+1])/2)
(list.append((list[i] + list[i+1])/2))
( list.sort())
else:
( list)
Z = [1,2,4,4.5]
test(Z,1.5)
Z = [1,2,3.0,4,4.5]
This is the only scenario that works. If none exceed the threshold or if there are two multiple that do exceed it does not work. I know I'm heading in the right direction
Simply break when you append the new number. Below is an edited version of your function. Also note I've adjusted the range of the for loop to prevent an index error. When comparing list[i] and list[i+1], i+1 can't be larger than the list size, so i must stop at len(list)-1
def test(list, Threshold):
for i in range(len(list)-1): # <-- note the change in limit
if abs(list[i] - list[i+1]) > Threshold:
list.append((list[i] + list[i+1])/2)
list.sort()
break # this will stop the loop
Tested
z = [1,2,4,4.5]
test(z,1.5)
z
[1, 2, 3, 4, 4.5]