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 7 years ago.
Improve this question
In Python, I have come to the realisation that when writing an expression, you can use brackets if you want to. I'll give you an example:
while count > 10:
and
while (count > 10):
are both accepted by the compiler.
My question is what are the best practices when using brackets for expressions in python? i.e. when should you use brackets in expressions?
In the example you provide, brackets are not necessary. They clutter the code without any particular reason (that I can think of)
Some reasons to use brackets. Use brackets to:
1) Improve code clarity
a * b + c and (a * b) + c are equivalent, but the latter is clearer. The clarity aspect is even more evident when combining more complex code, like ternary operations.
2) Override default order of operations
(a + b) * c and a + b * c give different behavior.
Similarly, X or Y and Z is different from (X or Y) and Z.
Additionally, use of brackets can alleviate the need for the programmer to memorize the implicit order of evaluation by explicitly specifying the order.
I always write brackets because I'm used to from languages that actually require them (C, Java...). In my opinion it is also make the code easier to read.
However, brackets are only useful when actually needed, like computing compound expressions. There's no really other reason to add brackets.
Only when it creates clarity of purpose.
if (condition_one and condition_two) or condition_three:
is okay, even though if you remove the parens it still works identically. It's not immediately obvious that and has a higher operator precedence than or (unless you've taken the time to memorize it). Similarly no one faults you for doing that with the math:
(2 * 3) / 6
Obviously if you need to override operator precedence, brackets are the way to do it
(2 + 3) / 6 != 2 + 3 / 6
condition_one and (condition_two or condition_three) != \
condition_one and condition_two or condition_three
However parens do add extra "noise" to the line that isn't necessary. Use them sparingly and only when actually necessary.
if (this) and (that) and (the_other):
should be
if all([this, that, the_other])
or at least
if this and that and the_other
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 1 year ago.
Improve this question
for pl in pokemon_list:
if pl["pokemon"] == showtype:
result = f"stamina: {'{:.2f}'.format((pl['stamina']/statmax)*100)}% ("
for i in range(pl["stamina"]):
result += "*"
How do I convert the code above to a more pythonic way?
First, using str.format() inside of an f-string is not sensible. Pick one
technique or the other, depending on the situation. For readability and
maintainability, do the computations outside of the f-string. An f-string is an
awkward context for computation; but it's perfect for simple variable
interpolation. In your case, you'd probably be better off sticking to
format().
Second, list comprehension is just a tool. It's not the holy grail of Python.
Select the tool only when it makes sense. One key test is whether you want
to create a list. You do not, as far as I can tell.
Your comment implies that you want to return the first matching item during the
iteration. If so, just do it. While you're at it, help your reader by using
convenience variables to reduce the visual weight of the code.
fmt = "stamina: '{:.2f}'% ({}"
for pl in pokemon_list:
if pl["pokemon"] == showtype:
s = pl['stamina']
return fmt.format(100 * s / statmax, '*' * s)
Could this be rewritten in the style of a comprehension? Yes, but it would be
less readable, even after breaking it apart into three lines of code. Avoid the
temptation to write overly fancy code like this, which will just leave your
readers scratching their heads.
fmt = "stamina: '{:.2f}'% ({}"
gen = (
fmt.format(100 * pl['stamina'] / statmax, '*' * pl["stamina"])
for pl in pokemon_list:
if pl["pokemon"] == showtype
)
return next(gen, None)
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 5 years ago.
Improve this question
I'm working on something in python and I have several variables that are calculated by very long formulas. I've done some searching on this site, and I found that python allows for implicit line breaking, which would be a solution for me as I can stretch the formula over multiple lines:
line-breaking
Now currently I have been working in a different way. Let me give you an example, if A would be given by the following formula:
A = b + c + d + e
I would be coding it as:
A = b + c
A += d + e
I was wondering what would be the preferred method. Is there a computational advantage to use implicit line-breaking over my current method?
We'd need more context to be sure, but here are some example cases.
For strings, as an implementation detail of CPython, the explicit split would be better (sometimes much better), because there is an optimization for an add (a = a + b) or inplace add (a += b) where the add/iadd instruction itself is immediately followed by a store to the left-hand side of the add. That said, for strings, you'll get more reliable performance regardless of operand size or the specific Python interpreter by doing A = ''.join((b, c, d, e)) rather than repeated concatenation.
For ints, floats and complex types, the single line approach is going to be ever so slightly more performant, solely because it avoids an unnecessary store and load instruction, but the difference is trivial; they're all immutable, scalar values, so no in-place manipulation of values occurs regardless, you'll have the same number of temporaries created during processing, the only question is whether they get (briefly) bound to a local name or not.
Frankly, if it's not a matter of concatenating strings or sequences (the former should be done with ''.join, the latter with itertools.chain to get O(n) performance), the preferred approach is not line continuation characters (which can easily get messed up by invisible trailing white space) but simple parentheses for grouping. If the real names of A = b + c + d + e were too long to fit on a line, my preferred approach would be:
A = (b + c +
d + e)
PEP8 prefers to break lines before the next operator, not after, so strictly PEP8 code would be:
A = (b + c
+ d + e)
This is the approach supported by PEP8 (the Python style guide), which says:
The preferred way of wrapping long lines is by using Python's implied line continuation inside parentheses, brackets and braces. Long lines can be broken over multiple lines by wrapping expressions in parentheses. These should be used in preference to using a backslash for line continuation.
The only real case for using backslashes instead is when parentheses aren't a legal part of the grammar (the link includes an example for with statements).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have an assignment in which I have got a formula, let's say x+(y*z) and I have to convert it to a binary tree. I have looked online and I've seen keywords like infix and postfix, and they will help to convert the regular expression to a form that can further be easily converted to a binary tree.
My only problem is that I've never learned this infix or postfix method, so is there any other way to convert it, or is that the only way? I've tried by searching up, but these were the only results I got.
It's a hard problem for me to solve without using online resources.
Infix and postfix aren't methods per se as much as notations, or ways of representing the same formula. x+(y*z) is already in infix notation (because the operators are inside the equation). The other two notations are prefix (or polish notation), where the operators are before the operands (so x+(y*z) is + x * y z) and postfix (or reverse polish notation), where the operators are after the operands (so x+(y*z) is y x * x +). Postfix notation is useful since it can be easily implemented via a stack (so to calculate y x * x + you put y and x on the stack, then we see * which pops x and y from the stack and puts x*y back into the stack, then we put x into the stack and then we see + which pops z*y and x from the stack and puts x+(z*y) back onto the stack and boom there's your calculation)
You can convert from infix notation to postfix via the Shunting-yard algorithm (Wikipedia explains it better than I could)
You can thus easily represent an equation in postfix notation via a binary tree since you go through the equation, adding operands to a stack as leaves, and when you get to an operator you pop the first two nodes from the stack and create a new node with the operator as the parent and the operands popped off as it's children. Then push this tree back onto the stack. Repeat until you reach the end of the equation.
There are many parsing libraries available for this kind of work.
For example, using pyparsing:
from pyparsing import *
def rearrange(tks):
T=tks[0]
T[0],T[1] = T[1],T[0]
return tks
expr = Forward()
arithOp = Word( "+-*/", max=1 )
terminal = ( Word(alphas, alphanums)
| Word(nums)
| Suppress("(") + expr + Suppress(")") )
expr << Group(terminal + arithOp + terminal).setParseAction(rearrange)
parseTree = expr.parseString("x+(y*z)")
print parseTree
will print:
[['+', 'x', ['*', 'y', 'z']]]
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 9 years ago.
Improve this question
Now I'm talking about MATH brackets, not python brackets, I know that parentheses () work like in maths, ex:
i = 5*(2+2)
print (i)
#output = 20
But square brackets [] and curly brackets {} don't work... (I know why they don't work)
Thank you,
Using Python 3.2.2
You don't need "math" brackets -- just use nested parentheses. Humans use [] in writing out complex math expressions to make them more readable to other humans, but this isn't necessary. They don't mean anything different than regular parentheses. So, when writing code, just stick to the parentheses.
They don't work as grouping constructs - only parentheses will do that.
Square brackets define a list.
Curly brackets define either a set or a dictionary (if the elements appear as key: value).
Further to this, the extra level of clarity when dealing with multiple nestings is unnecessary, as most good IDEs will let you know when the parentheses count is imbalanced (and, you will also notice when the count is imbalanced from repetition).
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 2 years ago.
Improve this question
Is it considered bad style to assign values to variables like this?
x = "foobar" or None
y = some_variable or None
In the above example, x gets the value 'foobar'.
No, it's a common practice. It's only considered bad style for expressions that are considerably longer than yours.
The primary danger of doing something like this is the possibility that (in the second case) some_variable is False but not None (the integer 0, for instance) and you don't want to end up with y equal to None in that case.
I also feel a bit unconfortable using that kind of expressions. In Learning Python 4ed it is called a "somewhat unusual behavior".
Later Mark Lutz says:
...it turns out to be a fairly common coding paradigm in Python: to
select a nonempty object from among a fixed-size set, simply string
them together in an or expression. In simpler form, this is also
commonly used to designate a default...
In fact, they produce concise one-line expressions that help to eliminate line noise from the code.
This behavior is the basis for a form of the if/else ternary operator:
A = Y if X else Z
OP's syntax is perfectly fine.
The official name for "assignment with or" is null coalescing and there's actually a Wikipedia page about it now! https://en.wikipedia.org/wiki/Null_coalescing_operator
This question may be useful as well:
Is there a Python equivalent of the C# null-coalescing operator?