Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Am i must to use here else: or i have opportunity to remove it and just type return True
def some_function(x):
if another_function(x) == -1:
return False
else:
return True
EDIT: I know how to make this code compact with just one return. The main question is about else:.
Should i always use 'else:' even it is not necessary?
I myself believe that they are not necessary. Returning at the beginning of the function in case of edge cases is something that allows you to skip sometimes lots of indentations caused by elses:
def some_function(x):
if edge_case_1:
return []
if edge_case_2:
return None
#a
#lot
#of
#code
#here
return result
looks better than
def some_function(x):
if edge_case_1:
return []
elif edge_case_2:
return None
else:
#a
#lot
#of
#code
#here
return result
right?
But it's not only about the looks:
Elses like that make you easily confuse the indentation levels.
The line width becomes smaller because the indentation takes those few character, you might need to format your code more to fit PEP8.
Sometimes you write the main part of the code first, only to discover the edge cases later. Version control systems such as git would mark all indented lines as changed (depending on the configuration), while the only thing you did was add those ifs at the beginning!
you can remove else and do like this:
def some_function(x):
if another_function(x) == -1:
return False
return True
Logically you can write
def some_function(x):
return another_function(x) != -1
else is not mandatory syntactically but there are few cases where you will get error
declare default value:-
var1 = some_value
if condition:
var1 = "something"
return var1
For the general case: since the return exits the function at this point and return control to the caller, the prefered idiom is :
def foo(x):
if <some_expression>:
return <something>
# we'll only ever get here if `<some_expression>`'s value is false
return <something_else>
As to why it's the prefered idiom (in python at least): the general consensus is that it makes the code more readable by 1/ flattening it (less indentation levels) and 2/ getting rid of all corner cases right from the start so the nominal case code is not polluted by such considerations. As a general rule, the simpler the code (and "flat" code is simpler than nested one, at least for the human brain) the easiest it is to understand.
Now for your own case where you are returning the boolean value of an expression, you don't even need a if statement at all - you can just directly return the result of evaluating the expression:
def foo(x):
return some_test(x) != some_value
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 months ago.
The community reviewed whether to reopen this question 5 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I am told that the following python-code does return me a true/false statement wether at least one element of the list "nums" is divisible by 7 (yeah, and for a 0). But let's say that the first value in the list is 14, so clearly divisible by 7.
I then would expect a return of "true" due to the "for" loop. And then the script continues and gives me the return "false", no matter what happend before that? Or does the skript abort after it finds a "true"? I thought I really understood how "return" works in python, but apparently not.
def has_lucky_number(nums):
"""Return whether the given list of numbers is lucky. A lucky list contains
at least one number divisible by 7.
"""
for num in nums:
if num % 7 == 0:
return True
return False
I would be very gratefull for some help here.
EDIT: apparently this seems to be unclear: I want to know WHY this skript returns "True" if nums has an element [14]. I know that it does that. But I would not expect it to do that because I would expect the last thing the code does to be to always return "False" due to the last line.
In most languages 'return' means you return a value and exit the function to the callee.
If you want it to "return" multiple values, essentially you want it to either return a list, or you want the function to be a generator.
A generator is something that yields rather than returns multiple values. So in your example you could instead do something like this:
def has_lucky_number(nums):
"""Return whether the given list of numbers is lucky. A lucky list contains
at least one number divisible by 7.
"""
for num in nums:
if num % 7 == 0:
yield True
else:
yield False
Which you would then use like this:
for value in has_lucky_number([1,2,5,14]):
# do something
Which would yield multiple values (four in total).
the 'return False' statement will only execute after the for loop. But if you enter another return statement before that it won't get executed.
Rule of thumb return statement ALWAYS exit functions.
return stop the for and return True if a number can be divided by 7. I tried with has_lucky_number([14,16]) and returns me True
The function end immediately after the first return statement.In this case,if the first number in the list is divisble by 7, the function will return True. If you want to see if all the numbers in the list are divisble by 7. You need to check them then return false or true at the end. You can use counter to see wich number is divisible by 0 then if the counter is equal to the list lenghtit returns true.
'return' means you return a value and exit the function to the callee.
If you want it to "return" multiple values, you can return a list.
This question already has answers here:
Is there shorthand for returning a default value if None in Python? [duplicate]
(4 answers)
Closed 12 months ago.
def test(x):
print("in test")
if x >0:
return 1
else:
None
def whennegative():
return 6
myval =test(3) if test(3) else whennegative()
Is there anyway do this one-line if-else without execute test twice? thanks
What you're writing can be summarized as "Do test(3) if it works, and if it doesn't, then here's a fallback". Put another way, that can be summarized as "Do test(3), or else do the fallback".
myval = test(3) or whennegative()
If test(3) is truthy, it'll short circuit out. Otherwise, it'll evaluate whennegative().
There are people who will argue that this is too short and clever, and it can certainly be overused (if you ever see a = (b and c) or d then you've gone too far). But a single or in assignment to mean "here's a fallback" or a single and to mean "here's a point of failure" is pretty well understood by folks and is, indeed, more concise than the ternary alternative.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Am learning python and one of the questions in our study guide asks to evaluate RNA sequences. I do not get the expected outputs as suggested by the question, I get 17.
Here is the code:
####START FUNCTION
def rna_length(mrna);
start_rna = 'AUG';
end_rna1 = 'UGA';
end_rna2 = 'UAA';
end_rna3 = 'UAG';
if (mrna[0:3]==start_rna) and (mrna [-3:]==end_rna1 or end_rna2 or end_rna3):
length = len(mrna[3:-3])
return length
else: ((mrna[0:3]!=start_rna) or (mrna [-3:]!=end_rna1 or end_rna2 or end_rna3))
return "Not readable RNA code"
####END FUNCTION
A link to a screenshot of the question here
The issue is you using the boolean operator or to compare strings. You can think of the comparisons like this:
(mrna [-3:]==end_rna1 or end_rna2 or end_rna3)
(((mrna [-3:]==end_rna1) or end_rna2) or end_rna3)
Because or is a boolean operator, it needs to work on booleans. You can convert strings to booleans using bool(<str>)
(((mrna [-3:]==end_rna1) or bool(end_rna2)) or bool(end_rna3))
Any string that is not empty (ie. any string that is not "") is "truthy." What that means is that bool(non_empty_str) == True and bool('') == False.
(((mrna [-3:]==end_rna1) or True) or True)
((True) or True)
(True or True)
True
Now, how should you fix it? There are a few approaches to this.
Properly use or.
if (mrna[0:3]==start_rna) and (mrna[-3:]==end_rna1 or mrna[-3:]==end_rna2 or mrna[-3:]==end_rna3):
length = len(mrna[3:-3])
return length
else:
((mrna[0:3]!=start_rna) or (mrna[-3:]!=end_rna1 or mrna[-3:]!=end_rna2 or mrna[-3:]!=end_rna3))
return "Not readable RNA code"
Use a collection. Note that it is standard to use tuples instead of lists whenever you don't want to modify the collection. I used lists here because the brackets look different. You can also use sets for quicker in, but that's overkill for 3.
if mrna[0:3] == start_rna and mrna[-3:] in [end_rna1, end_rna2, end_rna3]:
length = len(mrna[3:-3])
return length
else:
(mrna[0:3] != start_rna or mrna[-3:] not in [end_rna1, end_rna2, end_rna3])
return "Not readable RNA code"
Heck, you can even use the string methods str.startswith and str.endswith.
if mrna.startswith(start_rna) and mrna.endswith([end_rna1, end_rna2, end_rna3]):
length = len(mrna[3:-3])
return length
else:
...
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I'm trying to do something like this:
def func(varname):
varname = 1
func(x)
print(x)
But I get NameError: name 'x' is not defined
No, the syntactical construct you seem to be interested in is not possible. The reason is that function parameters are copies of the value (or reference) of the variable you pass in. Changing the value (or reference) of varname cannot change the value (or reference, for mutables) of x.
Now, the behavior that you want is totally possible. As a general rule, in order to have a function create a value and then assign that value to a variable name of your choice you use a return statement:
def funcname():
return 1
x = funcname()
print(x)
You need to declare the thing you are putting into the function as a parameter.
You should also actually do something with the value you are changing in the method.
In your example
def func(varname):
varname = 1
return varname #Return whatever you do to the input
x=3
x =func(x) #Do something with the value returned from your method
print(x)
Mostly the information you get back from a function is what is given in the return value. It's possible, even common, for functions to make changes in mutable data structures that they are passed (e.g. a list), especially where this is capturing state information or updating on the basis of other information handled by the function. And if you rearrange the contents of a list, the list elements will certainly have different values when the function exits.
Certainly you could do this:
def square_it(varname):
return varname*varname
x = square_it(3)
print(x)
giving output of 9, of course. You can also assign x to something else so that they now both have the same value
y = x
x = square_it(y)
which in some senses "changes the name" of what is referring to the value 9 to y, and moves x on to refer to something else.
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 2 years ago.
Improve this question
I'm trying to use a list of values to alter a bunch of class values that I added to another (temporary) list.
class game_events():
def __init__(self):
self.stage = 0
self.rules = False
saved_vars = [12, True]
game = game_events()
i = 0
for x in [game.stage, game.rules]:
x = saved_vars[i]
i+=1
It seems like everything is working, but that only the temporary list is being altered, like a decoy.
Desired results:
game.stage == 12
game.rules is True
Actual results:
game.stage == 0
game.rules is False
Any ideas?
When you do x = saved_vars[i], you're rebinding the variable x, not modifying the game object where it's previous value came from. If you want to modify just a few attributes on game, it's a whole lot easier to just do so directly:
game.stage, game.rules = saved_vars[0:2]
If you have a whole lot of attributes to go through, rather than just two in this example, you might return to your loop idea, but you'd need to do it differently. Rather than an assignment, you'd need to use setattr. And that means you'll need to specify the name of the attributes as strings, not with dotted notation:
for attr, value in zip(['stage', 'rules'], saved_vars):
setattr(game, attr, value)