This is working fine but I just don't get it why this works in this way. I think the return of True value should be inside the for loop but when I run this program it works in the opposite way.
Can someone point out what i am misunderstanding about the indentation of return values?
Even though the solution was even shorter I wanted to know exactly about my way of coding. Please help!
# My attempt
def palindrome(s):
mylist = list(s)
j = -1
for i in range(0,len(mylist)-1):
if mylist[i] == mylist[j]:
i+=1
j-=1
continue
return False
return True
# Solution answer:
def palindrome(s):
return s == s[::-1]
When a function is called, the function can return only once.
This kind of return pattern is very frequently found across various programming languages. It is intuitive and efficient.
Let's say you have to check if a list of 1000 values contain only even numbers. You loop through the list and check if each element is even. Once you find an odd number, you do not need to go further. So you efficiently and immediately return and exit from the loop.
Here is hopefully a little bit more intuitive version of your code:
def palindrome(s):
l, r = -1, 0 # left, right
for _ in range(0, len(s) // 2 + 1): # more efficient
l += 1
r -= 1
if s[l] != s[r]:
return False
return True
Once you know the input is not palindrome, you do not need to go further.
If you did not need to stop, it is palindrome.
They follow the exact same rules as any other statement. What you have written means
def palindrome(s) {
mylist = list(s)
j = -1
for i in range(0,len(mylist)-1) {
if mylist[i] == mylist[j] {
i+=1
j-=1
continue
}
return False
}
return True
}
# My attempt
def palindrome(s):
mylist = list(s)
j = -1
for i in range(0,len(mylist)-1):
if mylist[i] == mylist[j]:
i+=1
j-=1
continue
return False
return True
In the above code what happens is inside the for loop each time it checks if there is a mismatch in the values by comparing values by iterating over the list forwards using variable "i" and backwards using variable "j". and returns false immediately if any one letter mismatches and so exits from the loop. And true is returned only once the for loop is completed which means no mismatch was found in the loop
Note: i=0 gives first index, i+=1 iterates forward and j=-1 gives last index, j-=1 iterates backward
Basically, when you index an array in numpy, you do it the way:
a[start:end:step]
,for every dimension. If step is negative, you return the values in inverse order. So, if step is -1, the array a[::-1] is the inverted array of a[::].
a[::-1] = a[::]
Then, if a sequence is the same as its inverse, by definition, it is a palindrome.
See:
https://www.geeksforgeeks.org/numpy-indexing/
Related
My intention was to create (without the use of any module) a function which would index all zero rows of a matrix inside a list, here is the code I developed:
def check0(self):
L = []
for i in range(0, self._m):
for j in range(0, self._n):
if self[i, j] == 0:
if i not in L:
L.append(i)
return L
However at this point the function indexes the row as soon that it detects a zero in it, and I do not manage to find an additional condition for this to stop. Would anyone please have a solution?
The problem with your code is that it would add a row if at least one element of the row is zero. This would be a solution:
def check0(self):
L = []
for i in range(0, self._m):
for j in range(0, self._n):
if self[i, j] != 0:
break
else:
L.append(i)
return L
Here I am using the for else statement. The else clause is executed if the break statement inside the for is not reached, which only happens if all elements of the row are zero.
Assuming your previous questions deal with the same matrix class, you seem to store the data in a list of lists. In that case you can simply do
def check0(self):
return [i for i, row in enumerate(self._matrix) if not any(row)]
0 has a falsy value, so any(list_of_only_zeros) will return False.
If you wanted to implement the any() functionality yourself, it'd look like the following
indices = []
for i, row in enumerate(self._matrix):
contains_nonzero = False
for elem in row:
if elem != 0:
contains_nonzero = True
break
if not contains_nonzero:
indices.append(i)
Which is similar to the for else suggestion from the other answer. In this case the for else is a bit more succinct, since it saves you two lines not having to toggle the contains_nonzero flag.
nums.sort()
i = 0
for i in range(len(nums)-1):
if nums[i] == nums[i+1]:
i = i + 2
else:
return nums[i]
Could someone please explain why this code doesn't work? The logic is whenever I find a duplicate, I will jump two numbers ahead and compare that number to the one after.
Thank you.
You cannot edit what a "for loop" is going to interate through during the "for loop" itself. For example, "for i in range(10)" means i will take on the values of 0,1,2,...,9. That cannot be changed. Even if I manipulate i in some way, like "i = i +7" or "i = str(i)" that does nothing to change what i will become during the start of each loop.
I don't think what you're trying is possible with a for loop, because like what #rdas mentioned you can't jump ahead by increasing i like that. If you want to stick with your idea then you'd better use a while loop (something like the following, changes might be required),
nums.sort()
i = 0
while i <= len(nums)-1:
if i == len(nums)-1:
print(nums[i])
break
if nums[i] == nums[i+1]:
i += 2
else:
print(nums[i])
break
Like previous answers have said, you can't change that i value within the for loop.
One option would be to use pythons built in count() function for lists:
for x in nums:
if list(nums).count(x) == 1:
print(x)
An alternative solution would be to use the counter method in the collections package, iterate over your array items and and check whether the count is equal to one:
[x for x, count in collections.Counter(nums).items() if count == 1][0]
Better to use XOR operation for this problem, considering these properties:
XOR of a number with itself is 0.
XOR of a number with 0 is
number itself.
def singleNumber(self, nums: List[int]) -> int:
result = nums[0]
for i in range(1,len(nums)):
result = result ^ nums[i]
return result
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
def check(x,num,i):
for n in range(len(x)):
if x[i] == num:
return True
else:
return(check(x,num,i+1))
return False
def User(x,num):
return(check(x,num,0))
User([2,6,1,9,7,3],5,0)
this should out put false since 5 is not in the list
checks whether an element occurs in a list recursively
so for example:
Input: a list L read from the keyboard, for example L = [2,6,1,9,7,3]
an element e, for example e = 9
but for some reason, i get an error when the number is not in the list
The beauty (and purpose) of recursion is that you do not need the loop:
def check(x, num, i):
if not x[i:]: # index past length
return False
if x[i] == num:
return True
return(check(x, num, i+1))
You can also do without the index parameter:
def check(x, num):
if not x:
return False
return x[0] == num or check(x[1:], num)
I don't exactly understand what you're doing, but this is a bizarre combination of recursion and iteration. If you're going to use recursion, it's worthwhile, at least for a basic recursive problem like this, to avoid iteration. Try something like this
def check(x, num, i = 0):
if i >= len(x):
return False
elif x[i] == num:
return True
else:
return check(x, num, i + 1)
This solution will work perfectly fine and is tail recursive so it will work quickly and optimally.
The way this works is it checks if the index, i, is out of bounds. If so, then it returns False. If it is in bounds, it checks if x[i] is equal to the number. If so, it returns True. If it is not, it returns check with the index increased and thus the recursion works.
First of all, your for loop doesn't make any sense. You never use that n and never go into the loop a second time, as you always return something in the first iteration. The return statement after the for loop is also unreachable, so your code could as well be
def check(x,num,i):
if x[i] == num:
return True
else:
return(check(x,num,i+1))
Then the actual issue is, that if you have a list with 5 elements for example, which does not contain the element searched for, you ask what the 6th is, although there is no 6th element, thus the error. You'd have to check whether the list contains 6 elements. So you check whether it has more than 5, return false if it does and continue if it doesn't. (Alternatively you could also check this at the start of the whole function)
def check(x,num,i):
if x[i] == num:
return True
else:
if len(num)>i:
return False
else:
return(check(x,num,i+1))
What you've done then is nothing but a overcomlicated, recursive for-Loop. You just increase i and compare, until you find the element or i is bigger than the list length. So this is equivalent to
def check(x,num):
for i in range(len(num)):
if x[i]==num:
return True
return False
It is very important that the return False is AFTER the for-Loop, as you only return, if you didn't find the element, even after iterating over the WHOLE list.
Also you can avoid indices. With a for-Loop you can directly iterate over the elements in a list:
def check(x,num):
for elem in num:
if elem==num:
return True
return False
This makes the variable elem become every element in you list, one after another.
Hi Im trying to create a search function in python, that goes through a list and searches for an element in it.
so far ive got
def search_func(list, x)
if list < 0:
return("failure")
else:
x = list[0]
while x > list:
x = list [0] + 1 <---- how would you tell python to go to the next element in the list ?
if (x = TargetValue):
return "success"
else
return "failure"
Well, you current code isn't very Pythonic. And there are several mistakes! you have to use indexes to acces an element in a list, correcting your code it looks like this:
def search_func(lst, x):
if len(lst) <= 0: # this is how you test if the list is empty
return "failure"
i = 0 # we'll use this as index to traverse the list
while i < len(lst): # this is how you test to see if the index is valid
if lst[i] == x: # this is how you check the current element
return "success"
i += 1 # this is how you advance to the next element
else: # this executes only if the loop didn't find the element
return "failure"
... But notice that in Python you rarely use while to traverse a list, a much more natural and simpler approach is to use for, which automatically binds a variable to each element, without having to use indexes:
def search_func(lst, x):
if not lst: # shorter way to test if the list is empty
return "failure"
for e in lst: # look how easy is to traverse the list!
if e == x: # we no longer care about indexes
return "success"
else:
return "failure"
But we can be even more Pythonic! the functionality you want to implement is so common that's already built into lists. Just use in to test if an element is inside a list:
def search_func(lst, x):
if lst and x in lst: # test for emptiness and for membership
return "success"
else:
return "failure"
Are you saying you want to see if an element is in a list? If so, there is no need for a function like that. Just use in:
>>> lst = [1, 2, 3]
>>> 1 in lst
True
>>> 4 in lst
False
>>>
This method is a lot more efficient.
If you have to do it without in, I suppose this will work:
def search_func(lst, x):
return "success" if lst.count(x) else "failure"
you dont need to write a function for searching, just use
x in llist
Update:
def search_func(llist,x):
for i in llist:
if i==x:
return True
return False
You are making your problem more complex, while solving any problem just think before starting to code. You are using while loops and so on which may sometimes becomes an infinite loop. You should use a for loop to solve it. This is better than while loop. So just check which condition helps you. That's it you are almost done.
def search_func(lst,x):
for e in lst: #here e defines elements in the given list
if e==x: #if condition checks whether element is equal to x
return True
else:
return False
def search(query, result_set):
if isinstance(query, str):
query = query.split()
assert isinstance(query, list)
results = []
for i in result_set:
if all(quer.casefold() in str(i).casefold() for quer in query):
results.append(i)
return results
Works best.
I've just started exploring the wonders of programming. I'm trying to write a code to identify numeric palindromes. Just looking at numbers and not texts. I'm trying to learn to use recursion here. But I'm just not getting anywhere and I can't figure out what's wrong with it.
My idea was to check first string vs the last, then delete these two if they match, and repeat. Eventually there'll be nothing left (implying it is a palindrome) or there will be a couple that doesn't match (implying the reverse).
I know there are better codes to finding palindromes in but I just wanted to try my hand at recursion.
So what's wrong?
def f(n):
global li
li=list(str(n))
if (len(li)==(1 or 0)):
return True
elif li[len(li)-1]==li[0]:
del li[0]
del li[len(li)-1]
if len(li)==0:
return True
if len(li)>0:
global x
x=''.join(li)
str(x)
f(x)
else:
return False
Thanks in advance!
A few comments
Why are x and li globals? In recursion, all variables should be local.
Why are you converting back and forth between str and list? You can subscript both of them
You need to return the result of your recursive call: return f(x)
Try these suggestions, and see how it works out.
Before looking into it too much, if (len(li)==(1 or 0)): doesn't do what you're expecting it to do. (1 or 0) will always evaluate to 1.
You probably want:
if len(li) in (1, 0):
There are a couple of problems with your solution. Let me analyse them line by line.
You don't need global statements if you don't intend to change variables outside of function scope. Thus, I removed two lines with global from your code.
li=list(str(n)): casting a string to a list is unnecessary, as a string in Python has a similar interface to an immutable list. So a simple li = str(n) will suffice.
if (len(li)==(1 or 0)):: although it looks OK, it is in fact an incorrect way to compare a value to a few other values. The or operator returns the first "true" value from its left or right operand, so in this case it always returns 1. Instead, you can use the in operator, which checks whether the left operand is an element of a right operand. If we make the right operand a tuple (1, 0), all will be well. Furthermore, you don't need parentheses around the if statement. You should write: if len(li) in (1, 0):
elif li[len(li)-1]==li[0]: is fine, but we can write this shorter in Python, because it supports negative list indexing: elif li[-1] == li[0]:
Because we don't use lists (mutable sequences) because of point 2., we can't do del li[0] on them. And anyway, removing the first element of a list is very inefficient in Python (the whole list must be copied). From the very same reason, we can't do del li[len(li)-1]. Instead, we can use the "splicing" operator to extract a substring from the string: li = li[1:-1]
if len(li)==0: is unnecessary long. In Python, empty strings and lists resolve to False if tested by an if. So you can write if not li:
if len(li)>0:: You don't have to check again if li is not empty -- you checked it in point 6. So a simple else: would suffice. Or even better, remove this line completely and unindent the rest of the function, because the body of the if in 6. contains a return. So if we didn't enter the if, we are in the else without writing it at all.
x=''.join(li): We don't need to convert our string to a string, because of the decision made in 2. Remove this line.
str(x): This line didn't do anything useful in your code, because str() doesn't modify its argument in place, but returns a new value (so x = str(x) would have more sense). You can also remove it.
f(x): This is a valid way to call a recursive function in Python, but you have to do something with its value. Return it perhaps? We'll change it to: return f(li) (as we don't have an x variable any more).
We end up with the following code:
def f(n):
li = str(n)
if len(li) in (1, 0):
return True
elif li[-1] == li[0]:
li = li[1:-1]
if not li:
return True
return f(li)
else:
return False
It's almost what we need, but still a little refinement can be made. If you look at the lines if not li: return True, you'll see that they are not necessary. If we remove them, then f will be called with an empty string as the argument, len(li) will equal 0 and True will be returned anyway. So we'll go ahead and remove these lines:
def f(n):
li = str(n)
if len(li) in (1, 0):
return True
elif li[-1] == li[0]:
li = li[1:-1]
return f(li)
else:
return False
And that's it! Good luck on your way to becoming a successful programmer!
Split the whole show out into a list, then just:
def fun(yourList):
if yourList.pop(0) == yourList.pop(-1):
if len(yourList) < 2:
return True # We're a palindrome
else:
return fun(yourList)
else:
return False # We're not a palindrome
print "1234321"
print fun(list("1234321")) # True
print "6234321"
print fun(list("6234321")) # False
def palindrome(n):
return n == n[::-1]
It's hard to tell what you intend to do from your code, but I wrote a simpler (also recursive) example that might make it easier for you to understand:
def is_palindrome(num):
s = str(num)
if s[0] != s[-1]:
return False
elif not s[1:-1]:
return True
else:
return is_palindrome(int(s[1:-1]))
number = int(raw_input("Enter a number: "))
rev = 0
neg = number
original = number
if (number < 0):
number = number * -1
else:
number = number
while ( number > 0 ):
k = number % 10
number = number / 10
rev = k + ( rev * 10 )
if (number < 1):
break
if ( neg < 0 ):
rev = ( rev * -1)
else:
rev = (rev)
if ( rev == original):
print "The number you entered is a palindrome number"
else:
print "The number you entered is not a palindrome number"
This code even works for the negative numbers i am new to programming in case of any errors
dont mind.