I was studying list comprehension and came across the possibility of adding several conditions. I do not know what behavior I expected, but I cannot explain what I am getting. Why does 1 turn into 3, 2 remains a 2, and 3 turns into 6?
a = [x if x % 2 == 0 else x * 2 if x % 3 == 0 else x * 3 for x in range(1, 11)]
output:
[3, 2, 6, 4, 15, 6, 21, 8, 18, 10]
Re-writing as a loop and converting the conditional expressions to full if/elif/else statements might help explain it:
a = []
for x in range(1, 11):
if x % 2 == 0:
temp = x
elif x % 3 == 0:
temp = x * 2
else:
temp = x * 3
a.append(temp)
For 1 it goes like this:
1 % 2 = 1, so it goes to else clause,
1 % 3 = 1, so it also goes to else clause
and it gets into x*3 which is 1*3 = 3
When you write x if condition else y, you get x only if condition is true. So since the condition is false, you go to the else clause. You can look at it like this:
x if x % 2 == 0 else (x * 2 if x % 3 == 0 else x * 3) for x in range(1, 11)
Related
I made code as follows to execute binary search in sorted list for my study.
Code to find which number of values 'x' are in the list 'ss'.
Problem is, it should execute as reducing range of list, but it doesn't work.
def bin_search(ss, x):
return bin_search_range( ss, x, range(len(ss)) )
def bin_search_range(ss, x, r):
print(r)
print("len(r)", len(r))
if len(r) > 0:
mid = ((r.start) + (r.stop)) // 2
print("start", r.start)
print("stop", r.stop)
print("mid", mid)
print("x", x," ss[mid]", ss[mid])
if x == ss[mid]:
print("----[x = ss[mid]----")
return print("answer", mid)
elif x < ss[mid]:
print("----[x < ss[mid]]----")
return bin_search_range(ss, x, r[:mid])
else:
print("----[x > ss[mid]]----")
return bin_search_range(ss, x, r[mid+1:])
else: # len(r) == 0
return None
#Except "return print("answer", mid)", I just wrote down the rest of the output to know the progress.
In the manner of recursion, I repeated slicing the list through mid(which is median of list).
Until the median and 'x' match.
Below median, in other words left of median. There was no problem finding the value in.
There was a problem when finding the value on the right side of the median.
Below are the results of the execution of bin_search ([1, 2, 3, 4, 5, 6, 7], 5).
[Execution Result]
bin_search ([1, 2, 3, 4, 5, 6, 7], 5)
range(0, 7)
len(r) 7
start 0
stop 7
mid 3
x 5 ss[mid] 4
----[x > ss[mid]]----
range(4, 7)
len(r) 3
start 4
stop 7
mid 5
x 5 ss[mid] 6
----[x < ss[mid]]----
range(4, 7)
len(r) 3
start 4
stop 7
mid 5
x 5 ss[mid] 6
.
.
.
#RecursionError: maximum recursion depth exceeded while calling a Python object
Since x = 5, ss[mid] = 6, shouldn't the range of range be reduced to (4,5)?
Just like my prediction below
[Expected Result]
range(0, 7)
len(r) 7
start 0
stop 7
mid 3
x 5 ss[mid] 4
----[x > ss[mid]]----
range(4, 7)
len(r) 3
start 4
stop 7
mid 5
x 5 ss[mid] 6
----[x < ss[mid]]----
range(4, 5)
len(r) 3
start 4
stop 5
mid 4
x 5 ss[mid] 5
----[x = ss[mid]----
answer 4
Besides, when len(r) becomes 0, I thought I would print None, but I can't get any output.
Doesn't None print out when all the runs are over? I thought None would be printed because there was no range to search anymore, but I don't know why it couldn't be printed.
No matter how hard I think about it, I don't know if there's a problem with the code. If you know anything about it, I'd appreciate it if you could help me.
I have a problem that runs like this:
I have an integer n, let n = 30.
I add n with another integer k. Say, k = 19
However, I want to keep n between x and y, say 20 and 35. So if n+k > 35 it jumps back to 20 at 36, then continue to add 13 (19-6=13), which the final answer is 33.
I have already done the problem from scratch, and it's lengthy. It looks like this:
def plus(n,k,x,y):
result= n+k
if result > y: #do sth
if result < x: #do sth
return result
My question is, is there any build-in method, in any library, that helps me to do this problem? Thanks a lot.
The modulo operator % performs the kind of wrapping you're looking for. a % b gives the remainder from dividing a by b, resulting in the following wraparound pattern:
>>> for i in range(-2, 12):
... print(f"{i} % 5 = {i % 5}")
...
-2 % 5 = 3
-1 % 5 = 4
0 % 5 = 0
1 % 5 = 1
2 % 5 = 2
3 % 5 = 3
4 % 5 = 4
5 % 5 = 0
6 % 5 = 1
7 % 5 = 2
8 % 5 = 3
9 % 5 = 4
10 % 5 = 0
11 % 5 = 1
(The results you see with a negative left operand aren't what you get in most languages. Most languages would give you -2 and -1 instead of 3 and 4, but the 3 and 4 answers turn out to be more useful.)
You want to stay in a range from x to y inclusive instead of 0 to y-1, so we need to add and subtract x to adjust the range % gives us:
def plus(n,k,x,y):
modulus = y-x+1
return (n+k-x) % modulus + x
Sample output:
>>> plus(30, 19, 20, 35)
33
>>> plus(30, 0, 20, 35)
30
>>> plus(30, 5, 20, 35)
35
>>> plus(30, 6, 20, 35)
20
>>> plus(30, -10, 20, 35)
20
>>> plus(30, -11, 20, 35)
35
You’re looking for the modulo operator: %
result = x + (n + k - x) % (y - x + 1)
After reading your response, you can try that loop
def plus(a, b, minvalue, maxvalue):
plusresult = a + b
while plusresult > maxvalue:
plusresult -= maxvalue - minvalue
return max(plusresult, minvalue)
What I've got to do is get to print out as 5 4 3 2 1
then 4 3 2 1 under that then 3 2 1 and so on, right now all I have is the first line so i'll get 5 4 3 2 1 or 6 5 4 3 2 1 but I can't seem to get it right when trying to get it to continue until it reaches 1
from random import choice
i=choice([5,6,7,8,9,10])
while i:
print(i, end=" ")
i -= 1
if(i <1):
break
A compact approach:
import random as rnd
length = rnd.choice([5, 6, 7, 8, 9, 10])
lst = [str(x) for x in range(length, 0, -1)]
while lst:
print(" ".join(lst))
lst.pop(0)
Replace range with xrange if you are using Python 2.7.
You need two loops, one to do the initial countdown (5, 4, 3, 2, 1), the other to loop through each of the lists you need to produce. For example:
from random import choice
i=choice([5,6,7,8,9,10])
for j in [*range(i,0,-1)]:
for k in [*range(j,0,-1)]:
print(k, end=" ")
print('')
You can try this.
from random import choice
x = choice([5,6,7,8,9,10])
while x > 0:
y = x
while y > 0:
print y,
y = y-1
print "\n"
x = x-1
A line of code has tripped me up:
>>> i = 1
>>> j = 1
>>> i += j > 0 and i
>>> print(i)
2
What is the underlying mechanic or system that makes this work? It seems like it's syntactic sugar for i = i + i if j > 0 else i, but that's a lot to unpack. Am I wrong? Is there another system in play I don't know?
Thanks!
EDIT:
For clarity:
>>> i = 3
>>> j = 2
>>> i += j > 1 and i
>>> i
6
Let's break it down:
In [1]: i = 1
In [2]: j = 1
Now, let's look at the expression i += j > 0 and i:
In [3]: j > 0
Out[3]: True
Because j, which is 1 is greater than 0, this evaluates to True.
In [4]: j > 0 and i
Out[4]: 1
Because j > 0 is True, the value of the boolean expression is the value of the right-hand side, namely 1.
Thus, i += j > 0 and i simplifies to i += i or i = i + i:
In [5]: i += i
In [6]: i
Out[6]: 2
Let's also consider your second example:
>>> i = 3
>>> j = 2
>>> i += j > 1 and i
>>> i
6
For the thrid line we have these transforms:
i += j > 1 and i
i = i + (j > 1 and i)
i = 3 + (2 > 1 and 3)
i = 3 + (True and 3)
i = 3 + 3
i = 6
In Python and and or do not return boolean values, but rather return one of the options presented to them which evaluates to the correct boolean value.
For example, and will return either the first False value it encounters, or the last True value:
>>> 1 and 3
3
>>> 1 and 0
0
Similarly, or will return the first True value it encounters, and otherwise return the first False value:
>>> 2 or 3
2
>>> 0 or 2
2
>>> False or 0
0
Basically, you should keep in mind that and and or do not necessarily return True/False, but return one of the elements presented to them which evaluates to True or False.
im trying to return the divisors of 2 numbers that i appended to an empty list. why is nothing being printed? im expecting for 1,2,3 to be returned to mw but i get returned "[]" and "none"
def fun (t,g) :
list1 = []
i = 1
r = 1
while i < t :
if i % t == 0 :
list1.append(i)
i = i + 1
while r < g :
if r % g == 0 :
list1.append(r)
r = r + 1
print list1
x = 4
y = 6
t = fun(x,y)
print t
i % t is never 0 since you are exiting the while loop when i == t. Perhaps you meant t % i?
Likewise for r and g.
Your function doesn't have a return so it will implicitly return None
You should add return list1 to the end of it.
def fun (t,g) :
list1 = []
i = 1
r = 1
while i < t :
if t % i == 0 :
list1.append(i)
i = i + 1
while r < g :
if g % r == 0 :
list1.append(r)
r = r + 1
print list1
return list1
x = 4
y = 6
t = fun(x,y)
print t
prints
[1, 2, 1, 2, 3]
[1, 2, 1, 2, 3]
So you still need to work out the duplicates