Why is my condition expression giving a syntax error? - python

def singleNumber(nums):
for num in set(nums):
return num if nums.count(num) != 2 #error occurs here
print(singleNumber([1,1,4,5,5]))
This follows the usual python condition expression format. I don't understand why it's giving me a syntax error here.
The purpose of this function is to find number that doesn't occur twice.

If you're going to actually execute a return, you must return something no matter what.
So you could try:
return num if nums.count(num) != 2 else None
However, that's not going to work in this case since it will return on the first check rather checking all the elements for what you want.
In other words, let's say the first element checked is the first 1 in [1,1,4,5,5]. It will work out that there are two copies of that value in the array and then return None, skipping the rest of the elements.
I'd probably rewrite it as:
if nums.count(num) != 2: return num
which basically does what you need in that, if you don't explicitly return something (i.e., all of the values occur twice), the caller gets None implicitly when the function exits.
If you're the type that dislikes implicit things, you can explicitly add return None at the end of the function, though it's not really necessary.

Because you forgot to write what the result should be if the condition is false.
return num if nums.count(num) != 2 else ...what?
And if you didn't want that then you should write a normal if statement instead.

When you use a ternary conditional operator both if and else part are mandatory.
return num if nums.count(num) != 2 else <missing???>

Related

Python: How to exit all the recursions in a recursive function [duplicate]

I'm wondering how to break out of a recursive loop to the main function. I am trying to do a simple palindrome exercise. The function should return True for "redivider" but the return True is being passed to is_pal() and the function isn't breaking. Short of adding a second variable to is_pal to track True/False, what is the proper way to break out of this recursive loop?
def first(word):
return word[0]
def last(word):
return word[-1]
def middle(word):
return word[1:-1]
def is_pal(str):
if len(str) == 1:
return True
if first(str) == last(str) and len(str) > 1:
is_pal(middle(str))
print is_pal("redivider")
One way to break out of a recursive function in Python is to throw an exception and catch that at the top level. Some people will say that this is not the right way to think about recursion, but it gets the job done. Furthermore, if the task is to identify "problem" elements in an array/array of arrays/ndarray etc., a break technique is convenient, because it stops the algorithm from continuing after the global solution has been identified.
def solve_problem(lst):
def solve_rec(l):
'''has impl. that may throw an exception '''
try:
solve_rec(lst)
return True
except:
return False
def is_pal(str):
if len(str) <= 1:
return True
if first(str) == last(str):
return is_pal(middle(str))
else:
return False
That way, if they don't match, False is returned; if it makes it all the way to the end, True is returned. I also eliminated a redundant conditional and checked for the edge-case of an even-length palindrome.
You don't "break" out of recursive functions. Trying to do so says you're thinking about them the wrong way. Currently your recursive call is ignoring the output, which means that the recursion is pointless; whatever is_pal(middle(str)) returns has no effect on the return value of your function.
A recursive algorithm solves the input problem by decomposing the problem into a smaller problem, getting the solution to the smaller problem recursively, and then using the smaller solution to construct a correct solution to the larger problem. You don't "break" out of the inner calls, you return a solution back up one level. You don't know (or need to know) whether you're in an inner call or a top level call. In either case, your function should do the same thing: return True if the argument is a palindrome, and False if it isn't.
The algorithm you're trying to implement is basically this:
If the string is of length 1, it's a palindrome (return True)
Otherwise, if the first character is the same as the last character, then the input is a palindrome if the middle characters are a palindrome.
So what this means is that once you've established the first and last characters are the same, the answer to "is my input a palindrome" is exactly the same as the answer to "are the middle characters a palindrome". You need to return that answer to fulfil your contract. So the recursive call should be return is_pal(middle(str)) rather than just is_pal(middle(str)). If this was a top level call, then that's the answer; if this wasn't a top-level call, then the outer call is going to need this answer to work out the answer to the outer problem (in this case, by simply returning it).
Btw, your algorithm also has some other problems.
You never return False, so the answer can never be False (in this case you happen to accidentally return None by falling off the end of the function if the first and last character don't match, and None will probably do as a stand in for False in most cases, but it's still not really correct).
If the string's length is zero rather than 1 (which will happen if an empty string is passed in or if a palindrome of even length is passed in once all the pairs of equal first and last characters are stripped off), then you don't return the correct answer, and in fact you try to get the first and last character of the empty string, which will cause an exception.
You can exit the program after printing the results using the exit() function.
That may not be a good practice, but it might be what you're looking for.
You're missing a return. Also, don't use str as a variable name. Last thing, the first and last functions could be named slightly better.
def first_letter(word):
return word[0]
def last_letter(word):
return word[-1]
def middle(word):
return word[1:-1]
def is_pal(word):
if len(word) == 1:
return True
if first_letter(word) == last_letter(word) and len(word) > 1:
return is_pal(middle(word))
print is_pal("redivider")
You need to return False in case they don't match and add a return statement. Also you will probably want to check against len(str)==0 and len(str)==1:
def is_pal(str):
if len(str) in [0, 1]:
return True
if first(str) == last(str) and len(str) > 1:
return is_pal(middle(str))
else :
return False
YOU CAN BREAK RECURSION BY RETURNING 1 in 'if' statement before you write your 'function()' 2nd time.
I mean that's what we do to find factorial !! RIGHT? :)

Why break cannot be used in ternary operator in python? [duplicate]

I am trying to use if-else expression which is supposed to break the loop if the if condition fails, but getting an invalid syntax error.
Sample code:
a = 5
while True:
print(a) if a > 0 else break
a-=1
Of course, if I write in the traditional way (not using the one liner) it works.
What is wrong in using the break command after the else keyword?
If I run this, I get the following error:
... print(a) if a > 0 else break
File "<stdin>", line 2
print(a) if a > 0 else break
^
SyntaxError: invalid syntax
This is because
print(a) if a > 5 else break
is a ternary operator. Ternary operators are no if statements. These work with syntax:
<expr1> if <expr2> else <expr3>
It is equivalent to a "virtual function":
def f():
if <expr2>:
return <expr1>
else:
return <expr3>
So that means the part next to the else should be an expression. break is not an expression, it is a statement. So Python does not expect that. You can not return a break.
In python-2.x, print was not a function either. So this would error with the print statement. In python-2.x print was a keyword.
You can rewrite your code to:
a = 5
while True:
if a > 5:
print(a)
else:
break
a -= 1
You can read more about this in the documentation and PEP-308.
If is an expression, break similar to return is a statement. You can't use two statements in a single sentence (unless you use a semicolon which is ugly). I know it would have been really cool if we can do that, but alas that's the way it is.
To put it in slightly simpler terms, you're misusing the 'one-line if statement' (ternary operator). It always evaluates to an expression (i.e., a value). That is,
<expr1> if <condition> else <expr2>
evaluates to <expr1> if <condition> is True, and to <expr2> if <condition> is False. This resulting value can then be used like any Python value, for example:
y = 0
x = (5 if (y > 0) else 6)
print(x) # 6
Of course, the parentheses are completely unnecessary (even discouraged), but hopefully are useful for understanding the meaning of that line.
Therefore,
print(a) if a > 0 else break
tries to evaluate print(a) (which, by the definition of print() in Python 3, always returns None – perfectly valid, but probably not what you usually want) and then break, which does not evaluate to anything because it is a statement (action), not an expression (value), hence the invalid syntax error.
Hence, if you want to execute one of two statements depending on a condition, you really need the multi-line solution proposed by
Willem Van Onsem. There may be hacky ways to do it in one line, but multiple lines is the usual solution for something like this in Python.

PyCharm warns local variable might be referenced

Why does PyCharm highlight the boolean variable nearby the return with Local variable "boolean" might be referenced before assignment?
This code checks whether a number is prime or not:
import random
import math
import time
def prime_t(x):
print x
if x < 2:
return False
if x == 2:
return True
if x == 3:
return True
for i in range(2, int(math.sqrt(x))+1):
if x % i == 0:
boolean = False
break
else:
boolean = True
return boolean
random.seed()
how_much = input()
start = time.time()
for i in range(0, how_much):
print(prime_t(random.randint(0, 1000)))
print time.time()-start
I've read that might be some problem with global variables, but there's no ones which might be used in prime_t(). I had similar thing - exception while executing the code, but I think it has been eliminated with if x == 2 and if x == 3.
What else might be the problem?
PyCharm is not certain that boolean will be set. It is not smart enough to work out the flow of your code, so it doesn't know that your for loop will always have at least 1 iteration (since x > 3 is true by that point, provided x is an integer, of course).
Instead, it assumes that variables bound in a for loop could potentially never be set, and thus raises this warning.
The work-around is of course to set boolean = False before the loop, just to shut it up. It is only a warning, you could also just ignore it as the IDE is trying to help you but misunderstood.
Alternatively, instead of using a flag variable, you can use return False inside the for loop where you now use break, and return True at the end of your function:
def prime_t(x):
if x < 2:
return False
if x in {2, 3}:
return True
for i in range(2, int(math.sqrt(x))+1):
if x % i == 0:
return False
return True
For those looking to ignore this, put
# noinspection PyUnboundLocalVariable
Above the line.
Thanks to: https://github.com/whitews/pc-inspection-suppression-list/blob/master/suppress-inspection.csv
In general, code that's inside a for or while loop doesn't have to run. The condition for a while loop could be unmet as soon as the loop is reached initially. The for loop could be trying to iterate over something that's empty. If the loop doesn't run, and the code in the loop is the only place that a particular variable gets set, then it wouldn't get set. Trying to use it would cause an UnboundLocalError (a subtype of NameError) to be raised.
IDEs often try to detect this situation and offer warnings. Because they are warnings, they will be conservative. Python is a highly dynamic language and there's often very little that you can prove about the code's behaviour before it runs. So pretty well any loop that doesn't use constant, literal data (for x in [1, 2, 3]:) needs to be treated as "might not run at all".
And, indeed, if I try out the example function at the interpreter prompt, I can easily get that UnboundLocalError:
>>> prime_t(math.pi)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 14, in prime_t
UnboundLocalError: local variable 'boolean' referenced before assignment
After all, nothing else in the code type-checked the value; and pi isn't equal to 3, nor to 2, nor is it less than 2.
There are several reasonable approaches to the problem, in context.
We can simply assign boolean = True before the loop:
boolean = True
for i in range(2, int(math.sqrt(x))+1):
if x % i == 0:
boolean = False
break
return boolean
We can use an else clause on the loop to set the "default" value:
for i in range(2, int(math.sqrt(x))+1):
if x % i == 0:
boolean = False
break
else:
boolean = True
return boolean
The else block code runs whenever there isn't a break out of the loop; in particular, it runs if the loop doesn't run (since there was nothing to break out of). So static checking tools should be able to verify that our bases are covered. Many people don't like this syntax because it's confusing and often unintended (it looks like a typo, right?). However, this use pattern is pretty much exactly why it's in the language. (That said, I think we can do better; keep reading.)
Since there is nothing more to do after this loop in the function, we don't need a flag at all; we can return False as soon as we find a factor, and return True at the end of the function (since we didn't find one if we got this far):
for i in range(2, int(math.sqrt(x))+1):
if x % i == 0:
return False
return True
(Notice that in all of these cases, I removed the else from the if - because it doesn't serve a purpose here. It doesn't make a lot of logical sense to keep reminding ourselves that we didn't find a factor yet - we wouldn't still be looping if we did.)
All of that said, for "searching" loops like these I prefer to avoid explicit for loops altogether. The built-in any and all functions are practically designed for the purpose - especially when paired with a generator expression, which ensures their short-circuiting behaviour stays relevant:
return not any(x % i == 0 for i in range(2, int(math.sqrt(x))+1))
Equivalently (following de Morgan's law):
return all(x % i != 0 for i in range(2, int(math.sqrt(x))+1))

Return and assignment in recursive function in python: None type given, expected an int value

I am fairly new to python but worked with recursion previously. I came across this problem while working with recursive functions.
archive = {1: 0}
def engine(base, chain=0):
if base in archive:
return archive[base]
else:
if base == 1:
return chain
elif base % 2 == 0:
get = engine(base/2)
meaning = 1 + get
archive[base] = meaning
else:
next = 3 * base + 1
get = engine(next)
meaning = 1 + get
archive[base] = meaning
print archive(13)
I worked with scheme recently. So, I expected it to work.
I want the code to evaluate till the case bool(base==1) becomes true and then work it's way up ward making a new entry to the dictionary on each level of recursion.
How can I achieve that? I am just counting the level of recursion until the fore-mentioned condition becomes True with the variable 'chain'.
[Solved]: I missed the return statement in two clauses of if-else statement. The scheme would pass the function itself and the last return statement would do the work but not with python. I understand it now.
Thanks everyone who responded. It was helpful.
Your last two elif and else clauses have no return statements and Python returns None by default.

when to use if vs elif in python

If I have a function with multiple conditional statements where every branch gets executed returns from the function. Should I use multiple if statements, or if/elif/else? For example, say I have a function:
def example(x):
if x > 0:
return 'positive'
if x < 0:
return 'negative'
return 'zero'
Is it better to write:
def example(x):
if x > 0:
return 'positive'
elif x < 0:
return 'negative'
else:
return 'zero'
Both have the same outcome, but is one more efficient or considered more idiomatic than the other?
Edit:
A couple of people have said that in the first example both if statements are always evaluated, which doesn't seem to be the case to me
for example if I run the code:
l = [1,2,3]
def test(a):
if a > 0:
return a
if a > 2:
l.append(4)
test(5)
l will still equal [1,2,3]
I'll expand out my comment to an answer.
In the case that all cases return, these are indeed equivalent. What becomes important in choosing between them is then what is more readable.
Your latter example uses the elif structure to explicitly state that the cases are mutually exclusive, rather than relying on the fact they are implicitly from the returns. This makes that information more obvious, and therefore the code easier to read, and less prone to errors.
Say, for example, someone decides there is another case:
def example(x):
if x > 0:
return 'positive'
if x == -15:
print("special case!")
if x < 0:
return 'negative'
return 'zero'
Suddenly, there is a potential bug if the user intended that case to be mutually exclusive (obviously, this doesn't make much sense given the example, but potentially could in a more realistic case). This ambiguity is removed if elifs are used and the behaviour is made visible to the person adding code at the level they are likely to be looking at when they add it.
If I were to come across your first code example, I would probably assume that the choice to use ifs rather than elifs implied the cases were not mutually exclusive, and so things like changing the value of x might be used to change which ifs execute (obviously in this case the intention is obvious and mutually exclusive, but again, we are talking about less obvious cases - and consistency is good, so even in a simple example when it is obvious, it's best to stick to one way).
Check this out to understand the difference:
>>> a = 2
>>> if a > 1: a = a+1
...
>>> if a > 2: a = a+1
...
>>> a
4
versus
>>> a = 2
>>> if a > 1: a = a+1
... elif a > 2: a = a+1
...
>>> a
3
The first case is equivalent to two distinct if's with empty else statements (or imagine else: pass); in the second case elif is part of the first if statement.
In some cases, elif is required for correct semantics. This is the case when the conditions are not mutually exclusive:
if x == 0: result = 0
elif y == 0: result = None
else: result = x / y
In some cases it is efficient because the interpreter doesn't need to check all conditions, which is the case in your example. If x is negative then why do you check the positive case? An elif in this case also makes code more readable as it clearly shows only a single branch will be executed.
In general (e.g. your example), you would always use an if..elif ladder to explicitly show the conditions are mutually-exclusive. It prevents ambiguity, bugs etc.
The only reason I can think of that you might ever not use elif and use if instead would be if the actions from the body of the preceding if statement (or previous elif statements) might have changed the condition so as to potentially make it no longer mutually exclusive. So it's no longer really a ladder, just separate concatenated if(..elif..else) blocks. (Leave an empty line between the separate blocks, for good style, and to prevent someone accidentally thinking it should have been elif and 'fixing' it)
Here's a contrived example, just to prove the point:
if total_cost>=10:
if give_shopper_a_random_discount():
print 'You have won a discount'
total_cost -= discount
candidate_prime = True
if total_cost<10:
print 'Spend more than $10 to enter our draw for a random discount'
You can see it's possible to hit both conditions, if the first if-block applies the discount, so then we also execute the second, which prints a message which would be confusing since our original total had been >=10.
An elif here would prevent that scenario.
But there could be other scenarios where we want the second block to run, even for that scenario.
if total_cost<10:
<some other action we should always take regardless of original undiscounted total_cost>
In regards to the edit portion of your question when you said:
"A couple of people have said that in the first example both if statements are always evaluated, which doesn't seem to be the case to me"
And then you provided this example:
l = [1,2,3]
def test(a):
if a > 0:
return a
if a > 2:
l.append(4)
test(5)
Yes indeed the list l will still equal [1,2,3] in this case, ONLY because you're RETURNING the result of running the block, because the return statement leads to exiting the function, which would result in the same thing if you used elif with the return statement.
Now try to use the print statement instead of the return one, you'll see that the 2nd if statement will execute just fine, and that 4 will indeed be appended to the list l using append.
Well.. now what if the first ifstatement changes the value of whatever is being evaluated in the 2nd if statement?
And yes that's another situation. For instance, say you have a variable x and you used if statement to evaluate a block of code that actually changed the x value.
Now, if you use another if statement that evaluates the same variable x will be wrong since you're considering x value to be the same as its initial one, while in fact it was changed after the first if was executed. Therefore your code will be wrong.
It happens pretty often, and sometimes you even want it explicitly to be changed. If that's how you want your code to behave, then yes you should use multiple if's which does the job well. Otherwise stick to elif.
In my example, the 1st if block is executed and changed the value of x, which lead to have the 2nd if evaluates a different x (since its value was changed).
That's where elif comes in handy to prevent such thing from happening, which is the primary benefit of using it.
The other secondary good benefit of using elif instead of multiple if's is to avoid confusion and better code readability.
Consider this For someone looking for a easy way:
>>> a = ['fb.com', 'tw.com', 'cat.com']
>>> for i in a:
... if 'fb' in i:
... pass
... if 'tw' in i:
... pass
... else:
... print(i)
output:
fb.com
cat.com
And
>>> a = ['fb.com', 'tw.com', 'cat.com']
>>> for i in a:
... if 'fb' in i:
... pass
... elif 'tw' in i:
... pass
... else:
... print(i)
Output:
cat.com
'If' checks for the first condition then searches for the elif or else, whereas using elif, after if, it goes on checking for all the elif condition and lastly going to else.
elif is a bit more efficient, and it's quite logical: with ifs the program has to evaluate each logical expression every time. In elifs though, it's not always so. However, in your example, this improvement would be very, very small, probably unnoticeable, as evaluating x > 0 is one of the cheapest operations.
When working with elifs it's also a good idea to think about the best order. Consider this example:
if (x-3)**3+(x+1)**2-6*x+4 > 0:
#do something 1
elif x < 0:
#do something 2
Here the program will have to evaluate the ugly expression every time! However, if we change the order:
if x < 0:
#do something 2
elif (x-3)**3+(x+1)**2-6*x+4 > 0:
#do something 1
Now the program will first check if x < 0 (cheap and simple) and only if it isn't, will it evaluate the more complicated expression (btw, this code doesn't make much sense, it's just a random example)
Also, what perreal said.

Categories