I am trying to write a function which is supposed to compare list structures (the values are indifferent). The problem is that I have two lists which are unequal but the function still returns True even though it actually goes into the else part. I don't understand why and what I did wrong. Here is my code:
def islist(p): #is p a list
return type(p)==type(list())
def ListeIsomorf(a,b):
if len(a)==len(b):
for i,j in zip(a,b):
if islist(i) and islist(j):
ListeIsomorf(i,j)
elif islist(i) or islist(j):
return(False)
return(True)
else:
print(a,"length from the list isn't equal",b)
return(False)
#example lists
ListeE = [[],[],[[]]]
ListeD = [[],[],[[]]]
ListeF = [[[],[],[[]]]]
ListeG = [[],[[]],[[]]]
ListeH = [1,[3]]
ListeI = [1,3]
#tests
print(ListeIsomorf(ListeD,ListeE)) # True
print(ListeIsomorf(ListeD,ListeF)) # False
print(ListeIsomorf(ListeD,ListeG)) # False
print(ListeIsomorf(ListeH,ListeI)) # False
So the problem only occurs with the third print(ListeIsomorf(ListeD,ListeG)) # False. It actually goes into the else part and does print the "length from the list isn't equal" but it doesn't stop and it doesn't give out the return(False). Am I missing something?
The problem is that when your function calls itself recursively:
ListeIsomorf(i,j)
it ignores the returned value.
Thus the comparisons that take place at the second level of recursion have no effect on what the top level returns.
Changing the above to:
if not ListeIsomorf(i,j):
return(False)
fixes the problem.
Related
def p3(x,y,ls2):
for i in ls2:
if abs(i[0]-x)==abs(i[1]-y):
c=0
break
else:
c=1
if c==0:
return False
else:
return True
Even I have assigned c in the same function, it still displays "local variable 'c' referenced before assignment"
As the comment by Suraj S says, the problem is if ls2 is an empty list (iterable). Even if that were not a problem, c is a local variable inside the for loop and even though Python allows accessing it outside its scope, it is not a good practice to do so. So it is correct to default initialize it first before running the loop. You can default it to 0 or 1 depending on your use case.
Also, practice Boolean Zen. Don't make redundant checks with booleans. It is better to use True and False instead of 0 and 1.
def p3(x,y,ls2):
c = True # default
for i in ls2:
if abs(i[0]-x)==abs(i[1]-y):
c = False
break
# no need for else at all
return c
Even better:
def p3(x,y,ls2):
for i in ls2:
if abs(i[0]-x)==abs(i[1]-y):
return False
# no need for else at all
return True
If I understand correctly your function, you could simplify it to the following:
def p3(x, y, ls2):
# if no list or list is empty
if not ls2: # the condition could be more convoluted if needed
return 'invalid input' # or return boolean depending on use case
for i in ls2:
# if condition is matched return immediately
if abs(i[0]-x)==abs(i[1]-y):
return False
# the condition was not matched in loop, return default True
return True
You could even simplify more using all that will stop prematurely if the condition is met:
def p3(x, y, ls2):
# if no list or list is empty
if not ls2: # the condition could be more convoluted if needed
return 'invalid input' # or return boolean depending on use case
return all(abs(i[0]-x)!=abs(i[1]-y) for i in ls2)
# or: return not any(abs(i[0]-x)==abs(i[1]-y) for i in ls2)
In general, if you instantiate a variable (namely c) inside of a for loop, it's best not to use that variable outside of that for loop.
The practical reason for this is that you can't be sure that for loop will run and so the variable might not get instantiated. The more high-level reason is to maintain a sense of scope in your code, or "what happens in the for loop, stays in the for loop", if you will.
So in your case, I would recommend instantiating c with a 'default' value (depending on what your logic is) before the for loop starts, so that even if the for loop runs 0 times, c still has a value.
Alternatively, this entire function could be implemented as
def p3(x, y, ls2):
return not any([abs(i[0]-x)==abs(i[1]-y) for i in ls2])
def sudoku_solver(sudoku):
l = [0, 0]
if not find_empty_location(sudoku, l):
return True
row = l[0]
col = l[1]
for num in range(1, 10):
if check_location_is_safe(sudoku, row, col, num):
sudoku[row][col] = num
if sudoku_solver(sudoku):
return True,sudoku
sudoku[row][col] = 0
return False
def P():
a = np.zeros((9,9))
if sudoku_solver(sudoku):
a = sudoku_solver(sudoku)[1]
else:
a = 1
return a
There are two returns, True and sudoku. How can I call sudoku only in function P? When I run the function P(), it will show
'bool' object is not subscriptable.
You could make your function return a single value that would be either None or the sudoku data.
Python treats None as false so your condition could then be:
...
if sudoku_solver(sudoku):
a = sudoku_solver(sudoku)
...
Note that if sudoku_solver() is a complex and time consuming function, you will want to place its result in a variable BEFORE testing the condition so that it is not executed twice (as would be the case in the above condition)
...
a = sudoku_solver(sudoku)
if a:
...
Another option would be to systematically return a tuple with the boolean and the sudoku data (or None).
Your return statements would have to be changed to return True,sudoku and return False,None
Then your condition could use indexing directly:
...
if sudoku_solver(sudoku)[0]:
a = sudoku_solver(sudoku)[1]
...
but again, you probably don't want to execute the function twice so :
...
ok,a = sudoku_solver(sudoku)
if ok :
...
Another thing is that, if you're passing sudoku as a parameter, you have to realize that your function will modify the content of the calling variable even when it returns False. That may not be what you want but if it is, then there is no point in returning a second value because the caller's instance of the sudoku variable will already be modified and available.
When you see
return True,sudoku
you can catch the returned values like so
result, sudoku = my_function()
or if you've no interest in result
_, sudoku = my_function()
---Edit---
It seems your question centers around the two returns. Namely
return True,sudoku
versus
return False
That's adds unnecessary complexity. Can I suggest you simplify by instead using
return sudoku
and then later
return None
That means you can check the returned value like so
sudoku = my_function()
if (sudoku):
// Do something here
else:
// Do something else
You can't return multiple objects from a function, but you can return a container object, such as a list or tuple, that contains multiple member objects. Try using
return [ True, sudoku ]
I post simple code in order to understand how solve my problem. The while loop have 2 cycle but in real case have billion cycle.
def uno_trov():
if(1==1):
return True
else:
return False
def due_trov():
if(1==0):
return True
else:
return False
condizioneV = []
condizione = [1, 0] #1 or 0 inside can be change by the user
first_time = False
i=0
while(i<2):
if(first_time == False): #whit the first cycle I build condizioneV (list of functions)
if(condizione[0]==1):
condizioneV.append(uno_trov)
if(condizione[1]==1):
condizioneV.append(due_trov)
first_time = True
print(condizioneV) #I expect [True]
i+=1
else: #second time condizioneV is already builded and I suppose the process will be more fast because the code not check anymore " if(condizione[1]==1)"
print(condizioneV) #I expect [True]
i+=1
#problem is that I obtain "[<function uno_trov at 0x0272DED0>]" two time.
I don't understand the reason but I obtain "[]" two time. They aren't error but I didn't have a list with one or two True/False.
condizioneV.append(uno_trov)
appends the function address you're missing the ()
correction:
condizioneV.append(uno_trov())
General remark: your code is very poorly written and confusing. look at your first_time condition which is reversed for instance. And the indentation is terrible.
That's some pretty convoluted code you have there. I can't imagine what it is trying to do. I'll presume you are a beginner.
But the reason your arrays contains functions is that these two lines are appending the functions themselves into the arrays, the functions are not being executed.
Instead of this:
condizioneV.append(uno_trov)
condizioneV.append(due_trov)
You need to do this:
condizioneV.append(uno_trov())
condizioneV.append(due_trov())
Yes, this is a solution to one cycle but if you try to use it by pass a parameter to a function doesn't work anymore. I add "t=i" in the first if:
def uno_trov(t):
if(1==t):
return True
else:
return False
def due_trov():
if(1==0):
return True
else:
return False
condizioneV = []
condizione = [1, 1] #1 or 0 inside can change by the user
first_time = False
i=0
while(i<2):
if(first_time == False): #whit first cycle I build condizioneV
if(condizione[0]==1):
t=i
condizioneV.append(uno_trov(t))
if(condizione[1]==1):
condizioneV.append(due_trov())
first_time = True
print(condizioneV) #I expect [False]
i+=1
t=i
else: #second time condizioneV is already build but not properly work good
print(condizioneV) #I expect [True] but instead I get [False]
i+=1
t=i
In other words I would like that with first cycle I build the list of functions and from the second cycle to the end, execute the list of functions.
Hi i am new to Python programming . I am writing a python code which uses stack.
There are two function in my python code isdesc() and poisonplant()
When i have called the function poisonplant in there is another function but that function is not get called
Code is indented properly
Here is my code:
def isdesc(arr):
if len(arr) == 0:
return False
for i in range(0,len(arr)):
if arr[i+1] < arr[i]:
return True
else:
return False
def poisonplant(expr):
count=0
pdb.set_trace()
while not isdesc(expr):
s.push(expr[0])
for i in range(0,len(expr)):
if expr[i+1] < expr[i]:
s.push(expr[i+1])
count+=1
del expr[:]
for each_item in s.items:
a=s.pop()
expr.insert(0,a)
return count
input1=[6,5,8,4,7,10,9]
print(poisonplant(input1))
I have only called poisonplant and i think isdec is automatically get called inside poison function.
Can someone help me in this why isdesc is not get called here
isdesc is returning too soon, without looking at all the adjacent elements. It should read
def isdesc(arr):
for i in range(len(arr)-1):
if arr[i] < arr[i+1]:
return False
return True
(I've slightly modified the definition to treat empty lists as descending. If you treat an empty list as non-descending, you'll enter the loop, where you are assuming the list is not empty.)
Your main problem is that you're using return as if it will return each iteration, but you're actually just going to return on the very first one. You could instead return False if any of the sorts are wrong, but a better way to check if the lists are sorting in descending order is to check if the list is equal to a reverse sort of itself.
def isdesc(arr):
if len(arr) == 0:
return False
return arr == sorted(arr, reverse=True)
I have written the following code to check if some input to the function contains balanced brackets:
def balanced_brackets(text):
brackets = [ ('(',')'), ('[',']'), ('{','}'),('<','>')]
s = 0
e = 1
st = Stack()
for i in text:
for pair in brackets:
if i == pair[s]:
st.push(i)
elif i == pair[e] and not st.isEmpty() and st.pop() != pair[s]:
return False
if st.isEmpty():
return True
else:
return False
This code is working for input such as '()(())()' but it failed when I tried it for 'zn()((b)())q())()l()d(r)'. Can anyone help me identify what the problem is? Thanks.
Your problem is with the and not st.isEmpty()==0. When it gets to the unbalanced ')', all the previous ones have balanced out, so st is empty.
If you have a i == pair[e], and your stack is empty, you want to return False.
You also want to return False if you pop and it isn't pair[e]. But you don't want to pop if the stack is empty.
What you have now, in condition 1, just keeps going. You need to change around the condition there so that it accounts for both, or have two elifs. The former can be achieved with some nesting ands and ors.
By the way; unless you want to do something fancy with it, there's no real need to implement a stack. You can just use a list instead, with l.pop, len(l), and l.append.
This works.It needs a stack module to import. It will keep track of matched pairs.
def multi_bracket_validation(input):
""" test for matching brackets and return bool """
if type(input) is str:
open_b = '({]'
closed_b = ')}]'
compare = Stack()
for brac in input:
if brac in open_b:
compare.push(brac)
elif brac in closed_b:
if compare.top is None:
return False
if closed_b.index(brac) != open_b.index(compare.pop().val):
return False
return compare.top is None
return False