Reputation: 537
I am new to python.I have list of values like data = [100,50,3,205,10] and i am trying to write single function which will get a min and max value into tuple without using min ,max function
Here is my code and when i execute this i am getting ma,mi values (3,3) - which are incorrect.
passing data into findmax function
def findmax(data):
a = data
ma = a[0]
mi = a[len(a)-1]
k = 0
while k != len(a):
for i in range(0,len(a)):
k = i+1
if ma > a[i]:
ma = a[i]
continue
for l in range(0,len(a)):
if mi > a[l]:
mi = a[l]
print (ma,mi)
print(findmax([100,50,3,205,10]))
Upvotes: 1
Views: 3235
Reputation: 63749
Here is a different approach to single pass finding of min and max, by reading values two at a time. Instead of performing 2 comparisons per item, it performs 3 for every 2 items. This also uses an iterator to move through the input, and zip_longest
to go through the list in pairs:
from itertools import zip_longest
def minmax(data):
it = iter(data)
_min = _max = next(it)
for a, b in zip_longest(it, it, fillvalue=_min):
if a > b:
# swap items to make a <= b
a, b = b, a
if a < _min:
_min = a
if b > _max:
_max = b
return _min, _max
When the list elements are ints or floats, this improvement is not going to be measurable unless the lists are extremely long. But if the list items are complicated user objects, where > and < operations might involve some non-trivial amount of work, this might be worth pursuing.
Upvotes: 0
Reputation: 85
Here is an interesting way to do this using a bithack however any performance improvements you would see from something like this are so insignificant that the compromise between readability and performance is pointless.
def findminmax(data):
mi = ma = data[0]
for value in data:
mi = value if mi ^ ((value^mi) & -(value < mi))
ma = value if value ^ ((ma^value) & -(ma < value))
return mi, ma
Upvotes: 0
Reputation: 42133
You could do it in a single line, albeit very inefficiently, with a sort and list comprehension
minmax = [ (s[0],s[-1]) for s in [sorted(data)] ]
or, more seriously, you should take into account the possibility of being given an empty list.
minValue,maxValue = (data[:1] or [None])*2
for value in data[1:]:
minValue = value if value < minValue else minValue
maxValue = value if value > maxValue else maxValue
Upvotes: -1
Reputation: 889
Hello looping if you have a lot of elements in your list might take a toll on your computing time. I suggest do it in pandas instead
import pandas as pd
Then create a DataFrame using your data:
df = pd.DataFrame({'Values':data})
Using this code you'll get the max value:
print(df.loc[df['Values'].idxmax()]
You'll get:
205
Hope this helps :))
Upvotes: -1
Reputation: 1747
def minmax(ls):
if len(ls) == 0:
return None, None # or some default val
mini = maxi = ls[0]
for val in ls[1:]:
if val < mini:
mini = val
elif val > maxi:
maxi = val
return mini, maxi
This handles the case where input list length is 0. Also, I think having if-else-if makes more sense because if the value is smaller than minimum then there's no use performing the next check.
Upvotes: 1
Reputation: 1
You should be able to go over the list only once and save min and max values.
data = [100,50,3,205,10]
def findmax(data):
a = data
ma = a[0]
mi = a[0]
for item in data:
if item > ma:
ma = item
if item < mi:
mi = item
return (ma,mi)
print(findmax(data))
Upvotes: 0
Reputation: 1366
This might be helpfull. There's no need to loop over the input data twice.
data = [100,50,3,205,10]
def minmax(data):
_min = data[0]
_max = data[0]
for i in range(len(data)):
if _min > data[i]:
_min = data[i]
if _max < data[i]:
_max = data[i]
return (_min, _max)
Upvotes: 2