input in if condition in python - python

Can inputting and checking be done in the same line in python?
Eg) in C we have
if (scanf("%d",&a))
The above statement if block works if an integer input is given. But similarly,
if a=input():
Doesn't work in python. Is there a way to do it?

No, Python can't do assignment as part of the condition of an if statement. The only way to do it is on two lines:
a=input()
if a:
// Your code here
pass
This is by design, as it means that assignment is maintained as an atomic action, independent of comparison. This can help with readability of the code, which in turn limits the potential introduction of bugs.

You can't do it. This was a deliberate design choice for Python because this construct is good for causing hard to find bugs.
see #Jonathan's comment on the question for an example

Related

Why is the simple string "Guido" a valid statement in Python?

Why is this a valid statement in Python?
"Guido"
This tripped me up with a multi-line string where I did not properly use parens:
# BAD
message = "Guido"
" van Rossum"
# GOOD
message = ("Guido"
" van Rossum")
Is it purely for the repl or is there some other reasoning for it?
Expressions are statements in Python (and most other imperative languages) for several good reasons:
What if a function, like foo() does something useful but also returns a value? foo() would be an invalid statement if the language didn't allow us to implicitly discard the return value.
Docstrings! They are just strings that happen to be the first statement of a module/class/function, so no special syntax was needed to support them.
In general, it's hard for the interpreter to determine whether an expression might have side effects. So it's been designed to not even try; it simply evaluates the expression, even if it's a simple constant, and discards the result.
To check for such mistakes as you mentioned, and many others, pylint can be helpful. It has a specific warning for this very case. However, it seems to not catch the mistake in your exact example code (using PyLint version 2.4.4); might be a bug.

python To efficiently use the result of function in if statement

Is there any other code form, that one can both use a function in if statement and get the value of function without executing the function twice?
For example,
There exists a function, fun1(arg), which takes an hour to return its result (The result value can be either None or some int)
and I want to do some further calculation(for example get its squared value) only if the result from fun1 is not None.
This will be done by:
result = fun1(arg)
if result:
result = result * result
Is there any shorter form such as
if (result = fun1(arg)):
result = result * result
in python?
It may be more "clean" in a code manner, it is possible in C/C++ to do the 2nd one. Not in Python to the best of my knowledge. Moreover, the two examples you gave have the exact same needs in term of memory and computation. So it would be totally equivalent to use any of these two.
The two are absolutely identical. So my answer would be, go with your first method that you already know how to code 👍.
Do not over complicate when it is not necessary, it is a good piece of advice in general.
This is coming in a future version of python. See the following PEP
https://www.python.org/dev/peps/pep-0572/
It'll be known as an assignment expression. The proposed syntax is like;
# Handle a matched regex
if (match := pattern.search(data)) is not None:
# Do something with match
No you can't do this. Statements in Python not work as expressions in C with ;.
Well the second possible solution you wrote is incorrect since the 'result' variable in the if statement has no preassigned value. I would simply go with the first one...
What you are trying to do in your 2nd code is assignment inside expressions, which can't be done in Python.
From the official docs
Note that in Python, unlike C, assignment cannot occur inside expressions. C programmers may grumble about this, but it avoids a common class of problems encountered in C programs: typing = in an expression when == was intended.
also, see:
http://effbot.org/pyfaq/why-can-t-i-use-an-assignment-in-an-expression.htm

Python 'if' within assignment acceptable?

Friday I had a discussion with someone about the following contruction:
class C(....
c = C()
d = C()
...
(c if some_boolean else d).some_function_of_class_C()
Is this kind of if statement acceptable/encouraged?
The problem is that a lot of people I work with have C experience but not that much Python experience and are not used to such statement (same like list comprehension).
However, Python is not C and I think the advantages of the Python language should be used.
Or not?
(btw, I use normal function names and variable names but it is just for the sake of this example to keep it sample. Also I do not only call f() but some more functions (like f().g() which I woud have to repeat completely in that case.
There's nothing technically wrong with your code, but it is a little odd and surprising to see code like that.
Splitting your statement into two separate statements improves the readability:
c = c1 if some_boolean else c2
c.some_function_of_class_C()
The terrible variable names you have chosen still make it look awful. But changing the variable names also helps to improve the readability:
vehicle = plane if distance > 1000 else car
vehicle.travel()
That is a lot more readable than what you originally proposed, in my opinion, and it only took a very small change.
It is syntactically and semantically valid, but it certainly isn't Pythonic. Consider using the Strategy pattern instead.
Writing code in one language but using the styles and limitations of another language are never a good idea in the long run. Your python code should always be pythonic.
That said, make sure your code is readable assuming that the person reading the code understands python syntax, or at least enough to google the rest.

else vs return to use in a function to prematurely stop processing

[Edit] changed return 0 to return. Side effects of beinga Python n00b. :)
I'm defining a function, where i'm doing some 20 lines of processing. Before processing, i need to check if a certain condition is met. If so, then I should bypass all processing. I have defined the function this way.
def test_funciton(self,inputs):
if inputs == 0:
<Display Message box>
return
<20 line logic here>
Note that the 20 line logic does not return any value, and i'm not using the 0 returned in the first 'if'.
I want to know if this is better than using the below type of code (in terms of performance, or readability, or for any other matter), because the above method looks good to me as it is one indentation less:
def test_function(self,inputs):
if inputs == 0:
<Display Message box>
else:
<20 line logic here>
In general, it improves code readability to handle failure conditions as early as possible. Then the meat of your code doesn't have to worry about these, and the reader of your code doesn't have to consider them any more. In many cases you'd be raising exceptions, but if you really want to do nothing, I don't see that as a major problem even if you generally hew to the "single exit point" style.
But why return 0 instead of just return, since you're not using the value?
First, you can use return without anything after, you don't have to force a return 0.
For the performance way, this question seems to prove you won't notice any difference (except if you're realy unlucky ;) )
In this context, I think it's important to know why inputs can't be zero? Typically, I think the way most programs will handle this is to raise an exception if a bad value is passed. Then the exception can be handled (or not) in the calling routine.
You'll often see it written "Better to ask forgiveness" as opposed to "Look before you leap". Of course, If you're often passing 0 into the function, then the try / except clause could get expensive (try is cheap, except is not).
If you're set on "looking before you leap", I would probably use the first form to keep indentation down.
I doubt the performance is going to be significantly different in either case. Like you I would tend to lean more toward the first method for readability.
In addition to the smaller indentation(which doesn't really matter much IMO), it precludes the necessity to read further for when your inputs == 0:
In the second method one might assume that there is additional processing after the if/else statement, whereas the first one makes it obvious that the method is complete upon that condition.
It really just comes down to personal preference though, you will see both methods used in practice.
Your second example will return after it displays the message box in this case.
I prefer to "return early" as in my opinion it leads to better readability. But then again, most of my returns that happen prior to the actual end of the function tend to be more around short circuiting application logic if certain conditions are not met.

Does python officially support reusing a loop-variable after the loop?

Is the following code bad practice?
for i in some_values:
do_whatever(i)
do_more_things(i)
Somehow, it feels to me like the variable i should remain in the scope to the block inside the for-loop. However python 2.7 lets me reuse it after the loop.
Does python officially supports that feature, or am I abusing the language?
Yes, it's official:
for_stmt ::= "for" target_list "in" expression_list ":" suite
["else" ":" suite]
> The target list is not deleted when the loop is finished
http://docs.python.org/reference/compound_stmts.html#for
Note that a target list after for is far more than just a variable:
for some_list[blah] in...
for some_object.foo in...
for a[:n] in ...:
etc. These things cannot simply disappear after the loop.
Python can feel a bit special when it comes to scoping if you are coming from languages like C or Java. As previous answer says, the code is absolutely valid but I would recommend against it. It creates not particularly readable code and, furthermore, if some_values turns out to be empty, there will be an exception raised on the last line of the code.
So answer to your question is - yes, it is officially supported but in most cases it is not recommended strategy.
Interesting discussion can be found here and also local discussion on SO.
You can use this technique to scan a list for items matching some criteria:
for item in iter:
if interesting(item):
break
else:
raise ValueError('iter is boring.')
handle(item)
Just like #petr said, it sound unnatural. Not because it's allowed that it's natural or you have to use it.
I rather have something like this, although it may not apply to the logic with a break use-case:
for i in some_values:
do_whatever(i)
else:
do_more_things(i)
But this still raise NameError if some_values evaluate to empty, but sounds clearer. It does not give the clear readability of an inner scope but the indentation may suggests it.
But as other said, to answer to the specific OP's question, yes, it's legal.
That's not a feature. As you wrote the variable remains in the scope. It's normal interpreter behavior.

Categories

Resources