I've tried to write a function that takes three parameters: a linked list, a value, and a new value. The purpose of the function is to add the new value after the value in the linked list. Here's my function.
def addAfter(lis, value, newValue):
tracker = lis
while tracker != None:
if tracker['data'] == value:
newNode = {'data':newValue, 'next': tracker['next']}
tracker['next'] = newNode
break
else:
tracker = tracker['next']
For some reason I can't get this function to do anything. It doesn't change the list. I was wondering if someone could tell me what I'm doing wrong.
The problem is probably in how you're defining your initial nodes or list. For example, the following code works in Python3.4
def addAfter(lis, value, newValue):
tracker = lis
while tracker != None:
if tracker['data'] == value:
newNode = {'data':newValue, 'next': tracker['next']}
tracker['next'] = newNode
break
else:
tracker = tracker['next']
node1 = {'data':3,'next':None}
addAfter(node1,3,4)
print(node1)
print(node1['next'])
This outputs
{'next': {'next': None, 'data': 4}, 'data': 3}
{'next': None, 'data': 4}
As we'd expect it to. So there are several possibilities here
You're not using dictionaries at all - you defined a custom class and overloaded the setitem and getitem. I highly doubt this
You overloaded equals or hash so that the evaluations aren't correct. Doubt this too
You're using non-built-in objects as values and didn't overload the equals, so when you compare Foo() to Foo() it evaluates false. This seems somewhat likely. You might think that things are equal, when in fact Python is checking if they lie at the same memory location, not that their fields match
Your test code is wrong, you're printing out a copy of the data not the original data. This sort of thing is always a possibility
Try testing for each of those and let us know if none pan out. If not, provide a little more context, i.e., a scenario where the break is evident
Could you add a new class such as :
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
and then use the code of en_Knight, otherwise, the code will be hard to read
Related
Below is a code that divides each number of the node by 10. For example, node = 2->3->3, output would be 0.2->0.3->0.3.
However I am confused on why self.head.next gets updated each time given it's cur that receive the change. Suppose a=1,b=2 and we make a(cur)=b(self.head), if we change the value of a to 3, that wouldn't affect b, b is still 2. Therefore I couldn't understand why changing cur would affect self.head.next. Thank you!
class node(object):
def __init__(self,value,next=None):
self.value=value
self.next=next
class linkedlist(object):
def __init__(self):
self.head=None
self.next=None
def test(self,List):
self.head=node(0)
cur=self.head
while List:
s=List.value/10
cur.next=node(s)
cur=cur.next
List=List.next if List else 0
return self.head.next
Suppose below is the input:
a=node(2)
a=node(2,a)
a=node(3,a)
c=linkedlist()
Below is the output:
c.test(a).value=0.3
c.test(a).next.value=0.2
c.test(a).next.next.value=0.2
I am confused on why self.head.next gets updated each time given it's cur that receive the change
That is because, at least in the first iteration of the loop, self.head is cur:
cur=self.head
After that, it builds a new list with updated values, using a "dummy" node as self.head (and thus the first cur) which is then discarded and only it's next is returned. However, I find that code rather confusing and overly complicated (I had a hard time understanding it myself), e.g. the ternary ... if ... else ... in the last line is redundant as List can not be None at that point. Also, there's no need in making that a class, since none of its member attributes are used beyond the scope of a single execution of the method.
Instead, you could use a simple function, e.g. using a loop and modifying the original list, or even simpler, recursively creating a new list:
def div(lst, d=10):
first = lst
while lst:
lst.value /= d
lst = lst.next
return first
def div(lst, d=10):
return node(lst.value / 10, div(lst.next, d)) if lst else None
For easier debugging, you can also add a __repr__ method to your node class:
def __repr__(self):
return "(%r %r)" % (self.value, self.next)
There are two solution for a problem:
Problem is :
Enter the root node of a binary tree and an integer to print out the path where the sum of the node values in the binary tree is the input integer. A path is defined as a path from the root node of the tree to the next node until the leaf node passes. (Note: In the list of return values, the array with the largest array length is ahead)
solution one
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def FindPath(self, root, expectNumber):
if not root:
return []
result=[]
path=[root]
path_sum=0
def find(root,path,path_sum):
isleaf= root.left==None and root.right==None # a bool,whether is leaf node
path_sum+=root.val
if isleaf and path_sum==expectNumber:
t=[]
for i in path:
t.append(i.val)
result.append(t) # add a appropriate path's value to result
if path_sum<expectNumber:
if root.left:
find(root.left,path+[root.left],path_sum)#note!!!!!
if root.right:
find(root.right,path+[root.right],path_sum)#note!!!!!
find(root,path,path_sum)
return result
solution 2
class Solution:
def FindPath(self, root, expectNumber):
if not root:
return []
result=[]
path=[]
path_sum=0
def find(root,path,path_sum):
isleaf= root.left==None and root.right==None
path.append(root)#note!!!!!
path_sum+=root.val
if isleaf and path_sum==expectNumber:
t=[]
for i in path:
t.append(i.val)
result.append(t)
if path_sum<expectNumber:
if root.left:
find(root.left,path,path_sum)
if root.right:
find(root.right,path,path_sum)
path.pop()#note!!!!!
find(root,path,path_sum)
return result
I don't know why in solution 1 the path list don't need pop operation but solution 2 need. In other word why solution 1 don't share a path list, but solution 2 does.
Please help me, I cann't find such paper figure me out!
My point is not about class , you can use function to solve this problem too.
What I care is Python variable value assignment in recursion!!!
I find your code has a lot of mistakes that will make it hard to trace:
**** First: any def or function inside any Python class should be lower case with underscores, so we can figure out what is class from a function, so your FindPath() should be >>>>>> find_path()
**** Second: If you wand to declare any arguments to a the global scope of a class, you should do that inside a function as a constructor or initializer, so your code for an E.G should be :
class Solution:
def __init__(self, root, expect_number):
self.root = root
self.expect_number = expect_number
and any time you will call any argument inside the class, you should call it with the (self.arg), e.g self.root
**** Third: this line is not understandable at all :
def find(root,path,path_sum):
isleaf= root.left==None and root.right==None
this is totally wrong you are assigning a None value to preassaigned value to isleaf, and you again give the isleaf variable an (and) word so, as a logical or pythonic logic : how would the isleaf will understand to get the two values (root.left and root.right) which are getting a None values, does not make any sense.
so please give us an idea about what exactly do you want to do here.
**** Fourth: consider to give one space after and before any operator so instead of
"if path_sum
**** Don't afraid to give the variables or arguments a real names to discripe the real needs for it, or at least try to give a comment for it, So e.g : what is t = [] is doing!!!!!!!
So please try to be more specific so you can find good help for your problems, and to make your code more pythonic.
New Edit:
In solution no 2 : every time you call the find() function, you are appending or adding the 'root' value to the path list
def find(root,path,path_sum):
isleaf= root.left==None and root.right==None
path.append(root) # here you added the root to the path
and the code still recursive till this condition is false:
if path_sum<expectNumber:
and when it false, it will start to call the pop() method, which will remove
the last 'root', added to the path list:
path.pop()
and then it calls the next line, which will call the find function again
find(root,path,path_sum)
but this time will call it with empty path value, WHY?
because the first path list object "path=[]" is at the same level scope as
the calling of the last find function "find(root,path,path_sum)"
so the inner path argument and it's values not seen by the outer path scope, they only seen by the find() function it self.
And this scope issues exactly the same to "Solution 1", except you are passing a path list with root value, and when this condition is False
if path_sum<expectNumber:
the code will call the find() function again but with path only having the root value in the first announcement "path=[root]".
And After all I think with respect you are not sharing the whole code for privacy issue, so it's hard to find the answer easily.
You can simplify your recursive method several ways. First, at each iteration, check if the value of the node passed to the method along with the sum of the current path contents is less than or equal to the desired value. Second, should the latter be smaller, call the method on the left and right sides of the tree:
class Solution:
#classmethod
def find_path(cls, head, val:int, current = []):
if sum(current) == val:
yield current
elif head.value+sum(current) < val:
if head.left is not None:
yield from cls.find_path(head.left, val, current+[head.value])
if head.right is not None:
yield from cls.find_path(head.right, val, current+[head.value])
elif head.value+sum(current) == val:
yield current+[head.value]
Tree class for demonstration:
class Tree:
def __init__(self, **kwargs):
self.__dict__ = {i:kwargs.get(i) for i in ['left', 'right', 'value']}
t = Tree(value=10, left=Tree(value=8, left=Tree(value=3), right=Tree(value=5)), right=Tree(value=2, left=Tree(value=2)))
"""
10
/ \
8 2
/ \ /
3 5 2
"""
results = [list(Solution.find_path(t, i)) for i in [12, 14, 23]]
Output:
[[[10, 2]], [[10, 2, 2]], [[10, 8, 5]]]
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.
So I'm stuck here trying to recursively compare regexes with recursion. The user will create an object with two parameters, each a string of length one. These strings can only be "0", "1" or "2". But I want to recursively check if these strings point to another string as well. Like:
*
/ \
1 2
/ \
2 1
I can't figure out how to recursively point to a new object:
This is what I have so far:
class DotNode(object):
def __init__(self, _cargo, _left=None, _right=None):
self._cargo = _cargo
self._left = _left
self._right = _right
def __eq__(self, _other):
base = ['0','1','2']
if self._left in base and self._right in base:
return self._left == _other._left and self._right == _other._right
else:
while self._left not in base or self._right not in base:
new = self._left
new2 = self._right
new3 = _other._left
new4 = _other._right
return new._left == new3._left and new2._right == new4._right
You seem to already know how to do this: recursion. You want to call the __eq__function recursively here. I would also advice you check if the given cargo is one of the possible values in the constructor - or even better - every time the value is set.
class DotNode(object):
#property
def _cargo(self):
return self._vcargo
#_cargo.setter
def _cargo(self, val):
if val not in ['0', '1', '2']:
raise ValueError("{} is not a possible value for _cargo.".format(val))
self._vcargo = val
def __eq__(self, other):
return isinstance(other, DotNode) and self._cargo == other._cargo and self._left == other._left and self._right == other._right
Breaking it down
Of course you want to keep your constructor here. i just wrote the changed parts down. As you may have noticed you don't even need RegExes here, standard string comparison works just fine.
The _cargo property
I changed _cargo from a simple attribute to a property here. What does that mean? You get getters and setters à la Java that allow better control over the possible values. The actual data is stored in _vcargo of course someone could write to that attribute directly, but that would be downright stupid and you are certainly not responsible if someone uses your code in a way it was not intended. Should you try to set a value different from the possible values, a ValueError will be raised.
The __eq__ function
As you can see this function is actually very simple. Everything it does is compute whether the cargo of the node itself and the other node is equal. Now, if both subtrees are also equal the whole tree is equal. At the deepest level it will compare None with None if both trees are equal, because there will be no more subtrees.
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.