None Type object is not subscriptable - python

i try to fix it but, i cannot....
please help me, i do not know why it display that error.
def sorted_point_list(lst):
import math
def distance(point):
return math.sqrt(point[0]**2 + point[1]**2)
def max_point(lst):
def max_distance(lst):
if lst == []:
return 0
else:
return max(distance(lst[0]),max_distance(lst[1:]))
a = max_distance(lst)
for i in lst:
if distance(i) == a:
return i
def iter_(lst,result):
if lst == []:
return result
c = max_point(lst)
return iter_(lst.remove(c),c+result)
return iter_(lst,[])

This usually happens when you are getting None as a return value of something where you assume you'll be getting some other value (a list in this case).
Your max_point() function does not return a value in all cases. Therefore it returns None in those cases. This is a possible source of the error message you're getting.
Also, you're treating the remove() method of lists as though it returns a list. It does not; it modifies the list in place but returns None. This is also a possible source of the error.
As an aside, nesting functions the way you have is generally not a good idea. Inner functions will be redefined each time the outer function is called, which can be a significant performance penalty, especially if the outer function is called in a loop. (Similarly for the import, which will be executed each time you call sorted_point_list().)

problem seems to be this lst.remove(c), remove() changes the list in place and returns None. You're assuming it to be a list here.
Inside max_distance() you're passing lst[0] to distance(), and for None it'll raise the error None Type object is not subscriptable.

Related

Return value of the function when calling another function

This is what I encounter when trying to do a LeetCode question. I wrote a function to call another recursive function.
This is the way that the output is correct.
def generateParenthesis(self, n: int) -> List[str]:
right = n
left = n
item = ''
result = []
self.helper(item, left, right, result)
return result
def helper(self, item, l, r, result):
if l==0 and r==0:
return result.append(item)
else:
if l > r:
return
else:
if l > 0:
self.helper(item+'(', l-1,r, result)
if r > 0:
self.helper(item+')', l, r-1, result)
However, when I change the first function to this, I will get a empty list [].
def generateParenthesis(self, n: int) -> List[str]:
right = n
left = n
item = ''
result = []
return self.helper(item, left, right, result)
Cannot quite figure out how the return works in the function, need some help from you guys.
The helper function as shown in your source code uses tail recursion. This is evident from the fact that the helper function essentially stores information from the previous recursive call in its argument parameter; hence, the arguments are updated in each recursive call.
But even if this concept is foreign to you, as pointed out by #63677, we can commence from the observation that the helper function does not return anything. The return result.append(item) might seem like it is returning something, but the append function in Python does not return anything (it returns None). Therefore, all that helper does is to update the argument parameter until it hits the base case.
Calling self.helper(item, left, right, result) within the generateParenthesis function is going to alter the contents of result according to the operations defined in helper. The generateParenthesis then simply returns that altered result.
Your modified code doesn't work since helper does not return anything as it is defined (to be more technical, it is tail recursive instead of just recursive). Therefore, the modified code will not work since calling self.helper will simply return None.

Error returned from a Merge Sort function in Python

I have tried to write a Merge Sort function as you can see below. But when I try to test it I receive an error:
the name mergesort is not defined
Can anyone point out the cause for this error?
def merge(self,a,b):
sorted_list=[]
while len(a)!=0 and len(b)!=0:
if a[0].get_type()<b[0].get_type():
sorted_list.append(a[0])
a.remove(a[0])
else:
sorted_list.append(b[0])
b.remove(b[0])
if len(a)==0:
sorted_list+=b
else:
sorted_list+=a
return sorted_list
def mergesort(self,lis):
if len(lis) == 0 or len(lis) == 1:
return lis
else:
middle = len(lis)// 2
a = mergesort(lis[middle:]) #in pycharm the next 3 lines are with red underlined
b = mergesort(lis[middle:])
return merge(a,b)
The fact that self is one of the parameters to these methods means that they're most likely part of a class (one you've omitted from your post).
If that's correct, you need to invoke using self.mergesort(l), where l is a list.
As a pre-emptive measure against the next error you'll discover, you need to replace return merge(a, b) with return self.merge(a, b) for similar reasons.
Finally, I have to ask why you're defining all of these functions as methods of a class. They don't seem to rely on any shared data. Are you confident that they wouldn't be more appropriately declared at the module scope?

How to support two types of function arguments in python

I would like to design a function f(x) whose input could be
one object
or a list of objects
In the second case, f(x) should return a list of the corresponding results.
I am thinking of designing it as follow.
def f(x):
if isinstance(x, list):
return [f(y) for y in x]
# some calculation
# from x to result
return result
Is this a good design? What would be the canonical way to do this?
No, it's not good design.
Design the function to take only one datatype. If the caller has only one item, it's trivial for them to wrap that in a list before calling.
result = f([list x])
Or, have the function only accept a single value and the caller can easily apply that function to a list:
result = map(f, [x, y, z])
They can easily map over the function when they have a list(example):
def f(x):
return x + 1 #calcuation
lst = map(f, [1, 2, 3])
print(lst) # [2, 3, 4]
And remember: The function should do one thing and do it well :)
I'd avoid it. My biggest issue with it is that sometimes you're returning a list, and sometimes you're returning an object. I'd make it work on a list or an object, and then have the user deal with either wrapping the object, of calling the function in a list comprehension.
If you really do need to have it work on both I think you're better off using:
def func(obj):
if not isinstance(obj, list):
obj = [obj]
# continue
That way you're always returning a list.
Actually the implementation may be valid (but with room for improvement). The problem is that you're creating an ambigous and unexpected behaviour. The best way would be to have 2 different functions f(x) and f_on_list() or something like this, where the second apply the first to a list.

Adding items to a list if it's not a function

I'm trying to write a function right now, and its purpose is to go through an object's __dict__ and add an item to a dictionary if the item is not a function.
Here is my code:
def dict_into_list(self):
result = {}
for each_key,each_item in self.__dict__.items():
if inspect.isfunction(each_key):
continue
else:
result[each_key] = each_item
return result
If I'm not mistaken, inspect.isfunction is supposed to recognize lambdas as functions as well, correct? However, if I write
c = some_object(3)
c.whatever = lambda x : x*3
then my function still includes the lambda. Can somebody explain why this is?
For example, if I have a class like this:
class WhateverObject:
def __init__(self,value):
self._value = value
def blahblah(self):
print('hello')
a = WhateverObject(5)
So if I say print(a.__dict__), it should give back {_value:5}
You are actually checking if each_key is a function, which most likely is not. You actually have to check the value, like this
if inspect.isfunction(each_item):
You can confirm this, by including a print, like this
def dict_into_list(self):
result = {}
for each_key, each_item in self.__dict__.items():
print(type(each_key), type(each_item))
if inspect.isfunction(each_item) == False:
result[each_key] = each_item
return result
Also, you can write your code with dictionary comprehension, like this
def dict_into_list(self):
return {key: value for key, value in self.__dict__.items()
if not inspect.isfunction(value)}
I can think of an easy way to find the variables of an object through the dir and callable methods of python instead of inspect module.
{var:self.var for var in dir(self) if not callable(getattr(self, var))}
Please note that this indeed assumes that you have not overrided __getattr__ method of the class to do something other than getting the attributes.

Python why do my nested functions give a Nonetype error?

I'm new to programming.
def start():
x = 4
def addition():
n = 3
def exponential():
z = 2
def multiplication():
l = 2
print(x + n ** z * l)
return multiplication
equals = start()
equals()
why am I getting a "Nonetype" object is not callable error?
You're confusing a bunch of programming concepts:
Don't declare a function whenever you only need a statement
You're confusing function declaration with function call (invocation), and also the nesting is pointless. Declaring nested fn2 inside of fn1 doesn't magically also call fn2 and also transmit its return-value back to fn1. You still have to use an explicit return-statement from each fn.(If you forget that, you're implicitly returning None, which is almost surely not what you want)
For now, just don't ever nest functions at all.
Functions with no arguments are essentially useless, they can't take inputs and compute a result. Figure out what their arguments should be.
Specifically for the code you posted, addition(), multiplication() don't have any return value at all, i.e. None. exponential() returns multiplication, i.e. a function which only returns None. But then, both addition() and start() ignore that anyway, since they don't have a return-statement either, hence they implicitly return None.
Calling start() just gives you None, so you're just assigning equals = None. Not the result of some mathematical expression like you intended.
So:
reduce every unnecessary function to just a statement
declare each of your functions separately (non-nested)
each fn must have args (in this case at least two args, to make any sense)
each fn must have a return statement returning some value
only declaring a function and never calling it means it never gets run.
put an empty line in between function declarations (Then it's obvious if you forgot the return-statement)
Credits goes to #BrenBarn for being first to answer this. But I wanna post the code to make it more clear, and point out to some ways to make it better.
def start():
x = 4
def addition():
n = 3
def exponential():
z = 2
def multiplication():
l = 2
print (x + n ** z * l)
return multiplication()
return exponential()
return addition()
equals = start()
print equals #Output: 22
However, this is not the best way to list different methods. You should learn how to use a class in your python code.
I am going to define a class called "mathOperations". I will define three methods (functions): addition,exponential, multiplication. These functions are reusable.
class mathOperations():
def addition(self,x,y):
return x+y
def exponential(self,x,y):
return x**y
def multiplication(self,x,y):
return x*y
m= mathOperations()
z=2
l=2
x=4
n=3
result= m.addition(x,m.multiplication(m.exponential(n,z),l))
print result #Output:22
You should learn how to make your code reusable, try to google "procedural programming"; "Oriented Object Programming", or check "Learn Python the hard way" book. These are first and most used approach to make your code reusable. Think of it like a generic mathematical function to solve problems.

Categories

Resources