data structure list class in python - python

I am working on a data structure list class in python. I would like to get the largest item in the list.
inlist = self.data
if inlist[0] > inlist[1]:
largest = inlist[0]
else:
largest = inlist[1]
for item in inlist[2]:
if item > largest:
largest = item
return largest
With the above getting stuck at largest gets returns
<bound method ListData.largest2 of <list.ListData instance at 0x2b35602c3440>>
while the data
[2, 5]

Trust the loop to get all the indicies rather than specifying them yourself.
if len(self.data) == 0:
return None
result = self.data[0]
for item in self.data:
if item > result:
result = item
return result
that for loop is going through all your data. Trying to coerce an index got you into trouble.

You can use the build in max() function.
mylist = [2, 5]
mymax = max(mylist)

Related

Improving Python user defined max function

I am new to programming and am trying to understand how to "think" more programmatically in Python. I wrote a function that returns the largest element in an array without using max:
def max_userdefined(array):
"""
Finds largest value of nonempty array of numbers in O(n)
:param: list/tuple of values
:return: max value
"""
try:
assert isinstance(array, list or tuple)
result = array[0]
for element in array:
if element > result:
result = element
return result
except IndexError:
return 'Please pass in a nonempty array'
except AssertionError:
return 'Please pass in a list or tuple'
except TypeError:
return 'Please make sure elements of array are all floats or ints'
How can I improve the above code? Open to any criticism or if anyone can recommend a good Pythonic style guide.
def max_userdefined(array):
myMax = l[0]
for num in l:
if myMax < num:
myMax = num
return myMax
print max_userdefined ([1,2,3,4,5])
Output
5
Or You can do something like following by using sorted.
def max_userdefined(array):
return sorted(array)[-1]
>>> def umax(array):
global biggest
for num in array:
if num > biggest:
biggest = num
>>> biggest = int()
>>> nums = (1, 9, 6, 4, 5, 3, 2, 7, 0)
>>> umax(nums)
>>> biggest
9
For returning the greatest number from a list the simple algorithm followed is compare two numbers and keep the larger number in a variable, then print the variable OR you can use python shortcut using sort.
Using user defined function:
def greatest_ele_list(listobj):
greatest=listobj[0]
for i in range(len(listobj)):
if listobj[i]>greatest:
greatest=listobj[i]
else:
pass
return greatest
print greatest_ele_list([4,5,3,8,1])
Using sort:
def greatest_ele_list(listobj):
listobj2=listobj.sort()
return listobj2[-1]
print greatest_ele_list([4,5,3,8,1])
Output: >>> 8

Python: Functions and Lists?

I have a function that, when inputting a list and a specific string in that list, removes any duplicates of that specific string from the list. (find_start and find_end are separate functions that determine the first and last position of a certain string)
def remove_duplicates(sorted_list, item):
i = 0
real_list = []
for x in range(len(sorted_list)-1):
if(sorted_list[i] == item):
a = find_start(sorted_list, item)
b = find_end(sorted_list, item)
real_list = real_list + [item]
i = i+(b-a)
else:
real_list = real_list + [sorted_list[i]]
i+=1
return real_list
So for example, remove_duplicates(['a','a','b','b','c','c'], 'a') would return ['a','b','b','c','c']
I'm trying to define another function that uses this function in it for each iteration, like so
def remove_all_duplicates(sorted_list):
i = 0
list_tru = []
for x in range(len(sorted_list)):
list_tru = remove_duplicates(sorted_list, sorted_list[i])
i+=1
return list_tru
but if I input remove_all(['a','a','b','b','c','c']), it outputs ['a','a','b','b','c']. What am I doing wrong?
def remove_all_duplicates(L):
# NOTE: this modifies L IN-PLACE. Tread carefully
i = 1
while i<len(L):
if L[i] == L[i-1]:
del(L[i])
continue
i += 1
Usage:
In [88]: L = ['a','a','b','b','c','c']
In [89]: remove_all_duplicates(L)
In [90]: L
Out[90]: ['a', 'b', 'c']
With every iteration, you just keep going back to the original sorted_list. I would recommend copying it and then operating on that copy:
def remove_all_duplicates(sorted_list):
list_tru = sorted_list[:] # copy it
for x in set(sorted_list): # just use a set
list_tru = remove_duplicates(list_tru, x) # remove this character from your list
return list_tru
I've also turned the sorted list into a set so that you don't try to remove duplicates of the same letter multiple times, and removed the unnecessary i counter.
Of course, if all you really want to do is remove the duplicates from a sorted list of strings and you're not attached to the algorithm you're developing, that's particularly simple:
new_list = sorted(set(old_list))
def remove_duplicates(sorted_list):
for item in sorted_list:
hits = sorted_list.count(item)
while hits > 1:
sorted_list.remove(item)
hits = sorted_list.count(item)
return sorted_list
print(remove_duplicates(["a","a", "b", "b"]))
this is the simplest method I could come up with on the spot uses .count to tell if there are duplicates returns ["a", "b"]
You can use this too:
A = ['a','a','b','c','c'] #example of input list with duplicates
value = remove_duplicates(A) #pass the list to the function
print value #prints ['a','b','c']
def remove_duplicates(A):
B = [] #empty list
for item in A:
if item in B:
pass
else:
B.append(item) #Append the list
return B
Hope that this helps. Have a nice day.

Python Function with Lists and Sets

So I'm trying to figure out this problem and I can't figure out why it isn't working.
The premise is that you're given an input list and you have to find the second-lowest value. The list can have any number of integers and can repeat values; you can't change the list.
My code:
def second_min(x):
input_list = list(x)
print input_list
list_copy = list(input_list)
list_set = set(list_copy)
if len(list_set) > 1:
list_copy2 = list(list_set)
list_copy2 = list_copy2.sort()
return list_copy2[1]
else:
return None
print second_min([4,3,1,5,1])
print second_min([1,1,1])
The outputs for those two inputs are:
3
None
It's giving me errors on lines 9 and 13.
TypeError: 'NoneType' object has no attribute '__getitem__'
Thanks!
list_copy2 = list_copy2.sort()
.sort() sorts the list in place and returns None. So you're sorting the list, then throwing it away. You want just:
list_copy2.sort()
Or:
list_copy2 = sorted(list_set)
sorted always returns a list, so you can use it to sort the set and convert it to a list in one step!
You need to use sorted instead of sort. sorted returns a new list, that is a sorted version of the original. sort will sort the list in-place, and returns None upon doing so.
def second_min(x):
if len(x) > 1:
return sorted(x)[1]
else:
return None
>>> second_min([4,3,1,5,1])
1
Help, I can't use sorted! It's not allowed!
def second_min(li):
if len(li) < 2:
return None
it = iter(li)
a, b = next(it), next(it)
next_lowest, lowest = max(a, b), min(a, b)
for x in it:
if x < next_lowest:
if x < lowest:
lowest, next_lowest = x, lowest
else:
next_lowest = x
return next_lowest

How to speed up recursive call on Python linked list?

I have recursive function named min_max; it is passed a linked list; it returns a 2-tuple containing the minimum value followed by the maximum value. If the linked list is empty, then min_max returns (None, None). For example, if we called this function as min_max(list_to_ll([1, 3, 7, 2, 0])) the returned result would be (0, 7).
class LN:
def __init__(self,value,next=None):
self.value = value
self.next = next
def list_to_ll(l):
if l == []:
return None
front = rear = LN(l[0])
for v in l[1:]:
rear.next = LN(v)
rear = rear.next
return front
def min_max(ll):
if ll == None:
return (None,None)
else:
result = (ll.value,ll.value)
if ll.next != None:
return (min(result[0],min_max(ll.next)[0]),max(result[1],min_max(ll.next)[1]))
else:
return result
if __name__ == '__main__':
print('\nTesting min_max')
print(min_max(None))
print(min_max(list_to_ll([0])))
print(min_max(list_to_ll([7, 3, 5, 2, 0])))
print(min_max(list_to_ll([1, 3, 5, 2, 7])))
values = [i for i in range(1,100)]
print(values)
print(min_max(list_to_ll(values)))
My question is how do I speed up my recursive call min_max on the linked list with probably 100 elements? I can pass the test_case for linked with 5-7 elements but with 100 elements my function is not efficient. Thanks.
Currently, this line:
return (min(result[0],min_max(ll.next)[0]),max(result[1],min_max(ll.next)[1]))
calls min_max recursively twice to get the minimum and maximum - this means you make 2**n calls to min_max instead of n, which is a huge penalty. Instead, consider:
min_, max_ = min_max(ll.next) # call once
return min(min_, ll.value), max(max_, ll.value) # use the two values

object of type NoneType has no len

def medianeven (L):
while len(L) > 2:
L = L[1:(len(L)-1)]
return average (L)
def medianodd (L):
while len(L) > 1:
L = L[1:(len(L)-1)]
return L[0]
def median (L):
new = L.sort()
a = len(new)
if a % 2 == 0:
medianeven(new)
else:
medianodd(new)
It says TypeError: object of type 'NoneType' has no len(). Both medianeven and medianodd work, but median itself is not functioning.
.sort() is in-place and returns None.
Change this line:
new = L.sort()
To just this:
L.sort()
And replace all of your instances of new with just L. You also need to return the results of those function calls:
if a % 2 == 0:
return medianeven(new)
else:
return medianodd(new)
Also, Python's slices support negative indices, so this code:
L[1:(len(L)-1)]
Can be simplified to just
L[1:-1]
The sort() method call you have in the line:
new = L.sort();
doesn't return anything. Thus 'new' holds 'None', which has no length. I believe doing L.sort() will sort the list in place. Don't need to store it in 'new'.

Categories