This question already has answers here:
Does Python have a ternary conditional operator?
(31 answers)
Closed 8 years ago.
I'm having a difficult time learning python syntax. I've been doing some algorithms for a merge sort and I've run into a bit of an issue.
def arrMerge(a):
for i in range(1,len(a), *2):
for j in range(0,len(a)-1,2*i):
end2 = (2*i < len(a) -j) ? 2*i : len(a) -j
this block in python any ideas on how I should go about executing it?
I assume that you are asking what is the Python equivalent syntax to C++ ternary operator. In Python you would use a conditional expression that has the syntax value if condition else other_value.
So your assignment would become:
end2 = 2 * i if 2 * i < len(a) - j else len(a) - j
It is usually better to use a plain if though:
if 2 * i < len(a) - j:
end2 = 2 * i
else:
end2 = len(a) - j
Related
This question already has answers here:
Is there any method like divide by or multiply by in python range()?
(4 answers)
Closed 2 years ago.
The C code here:
for(i = 1; i <= 1000; i *= 3){
//task
}
How can I write this in python with a for loop?
So far I can only think of a solution using while loops:
i = 1
while i <= 1000:
#task
i *= 3
Is there a way I can write this with a for loop in python?
try this
step = 3
_i=1
for x in range(0,1000):
if x%_i!=0:
continue
_i*=step
# task
print(x)
This question already has answers here:
Python operators precedence
(2 answers)
Closed 2 years ago.
I have question about Python operator precedence.
print(not (8 < 4) or (10 == 5 * 2) and not (5 > 3))
The above code prints 'True'. But I think the result is 'False', with the following steps:
>>print(not F or T and not T)
>>print(T or T and F)
>>print(T and F)
>>print(F)
So I don't know why the result is 'True'
Maybe I'm missing the small detail.
and has higher precedence than or.
>>print(not F or T and not T)
>>print(T or T and F)
>>print(T or (T and F)) # Evaluated like this.
>>print(T or F)
>>print(T)
Adding the following (unnecessary) brackets will explain how it's getting evaluated:
print((not (8 < 4)) or ((10 == 5 * 2) and not (5 > 3)))
Since (not (8 < 4)) is evaluated to True (the other side of the or doesn't matter) this is the returned result
Here's the code, part of a solution to problem 11 in Euler Project:
sum_d = 0
j = 0
while j < 20:
i = 0
while i < 20:
try:
sum_d = grid[j][i] * grid[j+1][i+1] * grid[j+2][i+2] * grid[j+3][i+3]
if sum_d > result:
result = sum_d
except IndexError:
pass
i += 1
j += 1
My question is whether catching those exceptions is considered a code smell? I can see that it will be tougher to debug such code (say, I accidentally looped over 19 items instead of 20, it will be harder to trace) but it is much more elegant then, say, coding i < (GRID_WIDTH - NUM_ITEMS_IN_PRODUCT)
in the loop check.
P.S. I already solved the problem, I'm talking about the style of code
Spoiler: Here's part of my solution for problem 11.
for x in range(0,16):
for y in range(0,16):
prod = p[y][x] * p[y+1][x+1] * p[y+2][x+2] * p[y+3][x+3]
m = max(m, prod)
Using exceptions instead of basic control structures is imho always a bad idea. This time you can get away with looping through the numbers 0..15!
Also, if you muliply stuff you get a product, not a sum. ;)
You could at least make it
except IndexError:
break
Anyway, yes I believe this is a code smell, and no it is not clearer than
for i in range(gridsize - num_items_in_product):
I was wondering what the equivalent in python to this would be:
n = 100
x = (10 < n) ? 10 : n;
print x;
For some reason this does not work in Python. I know I can use an if statement but I was just curious if there is some shorter syntax.
Thanks.
x = min(n, 10)
Or, more generally:
x = 10 if 10<n else n
Here is the ternary operator in Python (also know as conditional expressions in the docs).
x if cond else y
There are various ways to make a ternary operation, the first one is the expression added with 2.5:
n = foo if condition else bar
If you want to be compatible with versions lower than 2.5 you can exploit the fact that booleans are subclasses from int and that True behaves like 1 whereas False behaves like 0:
n = [bar, foo][condition]
Another possibility is to exploit the way operators in Python behave or more exactly how and and or behave:
n = condition and foo or bar
>>> n = 100
>>> x = 10 if n > 10 else n
>>> x
10
10 if 10 < n else n
see http://en.wikipedia.org/wiki/Ternary_operation
x = 10 if (10 < n) else n
(requires python 2.5)
So I've got this snippet of code. And it works (It says 1 is non-prime).:
n = 1
s = 'prime'
for i in range(2, n / 2 + 1):
if n == 1 or n % i == 0:
s= 'non-' +s
break
print s
My problem is that if I change the fourth line to: if n % i == 0 or n == 1:, it doesn't work (it says 1 is prime.)
Why is that? Since I'm using or should it be that either one of them is True so the order doesn't count?
(I'm still learning about boolean so I may be making some basic mistake.)
Thanks in advance!
EDIT: Thanks for the answers; I never realized my issue with the range() function. And about the code working and not working: I have no idea what happened. I may have made some mistake somewhere along the way (maybe forgot to save before running the script. Although I could've sworn that it worked differently :P ). Maybe I'm just getting tired...
Thanks for the answers anyways!
In both cases, the body of the loop does not run, because when 'n' is 1, it does not fall within the range of (n,n/2+1)
The code you posted says that 1 is prime (again, because the loop body does not execute at all)
The precedence is fine. % is evaluated first, then ==, then or, so it breaks down into:
___or___
/ \
== ==
/ \ / \
n 1 % 0
/ \
n i
Your problem is that your for loop is not being executed at all, so that s is still set to "prime".
The range 2,n/2+1 when n is 1 equates to 2,1 which will result in the body not being executed.
In fact it won't be executed where n is 2 either since 2/2+1 is 2 and the range 2,2 doesn't execute. The values are the start and terminating value, not start and end (last) value - it's just fortuitous there that 2 is considered a prime by virtue of the initialisation of s :-)
Try this instead:
#!usr/bin/python
n = 9
s = 'prime'
if n == 1:
s = 'non-prime'
else:
i = 2
while i * i <= n:
if n % i == 0:
s= 'non-prime'
break
i = i + 1
print s
It's wasteful going all the way up to n/2, the square root of n is all that's needed.
i think the problem is when n is 1, the loop is skipped.
Other answers already correctly addressed your specific problem (which, in other words, is that the loop executes only if n/2 + 1 > 2, that is, n/2 > 1, which means n > 2 with new-style division [[python 3 or suitable imports from the future or flags...]], n > 3 with classic style truncating division).
Wrt the specific question you posed:
Since I'm using or should it be that
either one of them is True so the
order doesn't count?
The order does count because or (like and) is a short-circuiting operator: specifically, or is guaranteed to go left to right, and stop if the left operand is true (because it does not need to know about the right one). This doesn't matter for your specific code, but it's crucial in cases such as, e.g.:
if i == 0 or n / i > 3: ...
If or wasn't going left-to-right (and stopping ASAP), the right-hand operand might get executed even when i equals 0 -- but then the division would raise an exception! With Python's rules, this code snippet won't raise exceptions (if i is an int, at least;-).
Again: this has nothing to do with the specific problem you're having (see other answers and the start of this one), but it's important for you to know for the future, so, since you asked, I took the opportunity to explain!-)
for n in range(101):
s = 'prime'
if n < 2 or not (n & 1): ## not(n & 1) == is even number (last bit 0) == not (n % 2)
s = 'non-'+s
else:
for i in range(3, int(n**0.5) + 1,2):
if not(n % i):
s= 'non-' +s
break
print "%i is %s" % (n,s)
You need not check all even numbers and you can stop the check at square root of n.