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).
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 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
While programming in python 3.6, I came across with some problem in list :
l = [2,2,3,3,3]
for n in range(len(l)):
print(l[n+1]) #increasing value of n by 1
This code will obviously give an error :
IndexError: list index out of range
But in case of c language :
#include<stdio.h>
int main() {
int i =0;
int arr[5] = {1,2,3,4,5};
for(i = 0 ; i<=4;i++){
printf("%d " , arr[i+1]);
}
return(0);
}
Gives the correct output(including garbage value):
2 3 4 5 32764
I wanted to know why are we not getting the value of elements of list in python by using the future values of n whereas in c it is just reverse?
In C, an "array" is mainly a pointer to a memory location (nb: this is an obvious simplification, you can read this for more details), and arr[x] will return N bytes from address_of_arr + (N * x) (where N is the size of the array data type). Like all memory access in C, there's absolutely NO check so you can read (and write) just any arbitrary memory location.
Note that, as Daniel Pryden mentions in a comment, the behaviour you observe with your C example is called an "undefined behaviour", which means the result is not defined by the C langage specs, depends on the implementation (your C compiler, platform and whatnots), and could actually yield just any result (including a core dump, erasing your hard drive or launching a nuclear missile). Luckily the implementation you tested it with just returns garbage. Now if you really feel lucky, for a bit of fun try writing at this memory location and find out what happens ;)
In Python, a list is an object which knows it's length and won't let you try to access items at indexes that don't exist. Where and how the effective list contents are stored in memory is handled by the implementation and is totally opaque to the Python code.
Disclaimer : this answer is based on C implementations most commonly found on today's operating systems - the C language spec doesn't specify anything about how an array should be implemented (just how it's supposed to work) so an implementation could as well choose to store array datas on clay tablets disposed on a rubber band and move that rubber band by N positions left or right, in which case my answer would be totally irrelevant...
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 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
This question already has answers here:
How do you join all items in a list?
(4 answers)
Closed 8 years ago.
I ran into a problem when trying to shorten my script.
First of all this is my script:
letters_list = ['d', '7', '9']
letter_string = ""
for letter in letters_list:
letter_string +=letter
print letter_string
I need to put this whole thing into one line.
How can I do that?
You can simply join the characters with str.join like this
print "".join(letters_list)
# d79
Quoting from the documentation,
CPython implementation detail: If s and t are both strings, some Python implementations such as CPython can usually perform an in-place optimization for assignments of the form s = s + t or s += t. When applicable, this optimization makes quadratic run-time much less likely. This optimization is both version and implementation dependent. For performance sensitive code, it is preferable to use the str.join() method which assures consistent linear concatenation performance across versions and implementations.
So str.join is better than letter_string += letter way of joining strings.
letter_string = "".join(letters_list)