This is the code given below.
k = [1, 8, 15]
g = (x for x in k if k.count(x) > 0)
k = [2, 8, 22]
print(list(g))
I am getting the output as [8] but it should be [1,8,15], right? since each element is present at least once.
Any plausible explanation for the answer?
That's a generator expression. It creates a generator, not a tuple.
Exactly one part of a generator expression is evaluated at genexp creation time. It's this part:
g = (x for x in k if k.count(x)>0)
# ^
Everything else, including this part:
g = (x for x in k if k.count(x)>0)
# ^
is evaluated lazily.
That means the k you're looping over is the original k, but the k you're calling count on is the new k.
Here's a trick to see which k uses the original/modified list by printing x and k in the generator expression:
1st k refers to the original list:
>>> k = [1,8,15]
>>> g = (x for x in k if (print(x) == None and k.count(x)>0))
>>> k = [2,8,22]
>>> list(g)
1
8
15
2nd k refers to the modified list:
>>> k = [1,8,15]
>>> g = (x for x in k if (print(k) == None and k.count(x)>0))
>>> k = [2,8,22]
>>> list(g)
[2, 8, 22]
[2, 8, 22]
[2, 8, 22]
Debugging trick similar to Shawn's:
def p(label, x):
print(label, x)
return x
k = [1,8,15]
g = (x for x in p('iterate over', k) if p('count in', k).count(x)>0)
k = [2,8,22]
print('between generator construction and consumption')
list(g)
Output (Try it online!):
iterate over [1, 8, 15]
between generator construction and consumption
count in [2, 8, 22]
count in [2, 8, 22]
count in [2, 8, 22]
Generator is fetch on process memory,work like lazy operator so that happen
"""""for x in [1,8,15]:
if [2,8,22].count(x): """"
That is how interpreter fetch values.
Refer this tweet for more understand:
https://twitter.com/nedbat/status/1503735148378001410?t=lJLT482Vmt19cBNuP-PAWQ&s=19
https://twitter.com/driscollis/status/1503366898234404866?t=OgCM0E1rzWAEQOOziO9uqA&s=19
#Learning with hope
Related
I am trying to figure out how I can append the values in f_list given that it must satisfy the conditions:
The difference between the value in f_list and the previous value is greater than g.
The difference between the value in f_list and the value after is also greater than g.
This is the code I have established so far:
def func (f_list, g):
newlist = []
v = [f_list[i+1]-f_list[i] for i in range(len(f_list)-1)]
m = [f_list[i-1]-f_list[i] for i in range(len(f_list))]
for x in f_list:
for y in v:
for z in m:
if y > g and x>g:
new_list.append(x)
return newlist
readability is sometimes better than terseness
# cannot be first or last element
for i in range(1,len(my_list)-1):
left_diff = my_list[i] - my_list[i-1]
right_diff = my_list[i] - my_list[i+1]
if left_diff > g and right_diff > g:
new_list.append(my_list[i])
I guess it sounds like you want absolute difference, not just difference
if abs(left_diff) > g and abs(right_diff) > g:
...
You could use a zip:
from numpy import nan
l = [7, 9, 14, 10, 8, 16, 11, 18 ]
g = 3
[y for x,y,z in zip([nan]+l[:-1],l,l[1:]+[nan]) if (abs(y-x) > g) and (abs(y-z) > g)]
Out[23]: [14, 16, 11]
Given a list of numbers and a number k, return whether any two numbers from the list add up to k.
For example, given [10, 15, 3, 7] and k of 17, return true since 10 + 7 is 17.
n=0,
Axe= [10, 15, 3, 7],
uplimit=len(Axe)
for x in range(uplimit):
print(Axe[n])
print(Axe[x:uplimit])
print (Axe[n]+ Axe[x])
i am stuck here. i can get the fist value to be added with the rest, but dont know how to get the rest to do the same.
I can do it manually of course but i need to automate the process
This function should do the trick
def my_function(mylist, k):
for i in range(len(mylist)):
first = mylist[i]
for second in mylist[i:]:
print(f"{first} + {second} = {first+second}")
if first+second ==k:
return True
return False
You can also use itertools:
import itertools
def sum_pairs(num_list, k):
all_pairs = list(itertools.combinations(num_list, 2))
for pair in all_pairs:
if sum(pair) == k:
return True
return False
You can then call the above function:
Axe = [10, 15, 3, 7]
k = 17
print(sum_pairs(Axe, k))
list = [10, 15, 3, 7]
k = 17
for i in range(len(list)):
temp = list[i]
for i in range(len(list)):
if (temp + list[i] == k ):
print("true")
return
In the following code I want to add second parameters of list=[(0,3),(2,6),(1,10)] in a for loop. first iteration should be 3+6=9 and the second iteration should add output of previous iteration which is 9 to 10---> 9+10=19 and I want final output S=[9,19]. I am not sure how to do it, Should I add another loop to my code?
T=[(0,3),(2,6),(1,10)]
S=[]
for i in range(len(T)):
b=T[0][i]+T[0][i+1]
S.append(b)
use itertools.accumulate
spam = [(0,3),(2,6),(1,10)]
from itertools import accumulate
print(list(accumulate(item[-1] for item in spam))[1:])
output
[9, 19]
Use zip to combine the vales from the tuples, with the same index.
Use an assignment expression (from python 3.8), in a list-comprehension, to sum the values in the second tuple, T[1], of T.
T = [(0,3),(2,6),(1,10)]
T = list(zip(*T))
print(T)
[out]:
[(0, 2, 1), (3, 6, 10)]
# use an assignment expression to sum T[1]
total = T[1][0] # 3
S = [total := total + v for v in T[1][1:]]
print(S)
[out]:
[9, 19]
Just modify your code as below
T=[(0,3),(2,6),(1,10)]
S=[]
b = T[0][1]
for i in range(1,len(T)):
b+=T[i][1]
S.append(b)
This should help u:
T=[(0,3),(2,6),(1,10)]
lst = [T[i][1] for i in range(len(T))]
final_lst = []
for x in range(2,len(lst)+1):
final_lst.append(sum(lst[:x]))
print(final_lst)
Output:
[9, 19]
If u prefer list comprehension, then use this line instead of the last for loop:
[final_lst.append(sum(lst[:x])) for x in range(2,len(lst)+1)]
Output:
[9, 19]
Here is a solution with native recursion
import operator
mylist =[(0,3),(2,6),(1,10)]
def accumulate(L, i, op):
def iter(result, rest, out):
if rest == []:
return out
else:
r = op(result, rest[0][i-1])
return iter(r, rest[1:], out + [r])
return iter(L[0][i-1], L[1:], [])
print(accumulate(mylist, 2, operator.add))
print(accumulate(mylist, 1, operator.add))
print(accumulate(mylist, 2, operator.mul))
# ==>
# [9, 19]
# [2, 3]
# [18, 180]
I am iterating in a for loop, constructing a list, whilst comparing the last number of that list with another number.
I would like my code to see if the last item of the list is smaller than the item it is being compared to, and if it is, to add it to the end of its list and then to continue.
if the last item of the list is larger, i would like to pop off the last item of the list. i would then like to subject it to the same conditionals.
here is my code, it is not working, it wont re check the conditionals after popping off the last item of the list.
if tempList:
lastNum=tempList[-1]
#############################################
if element < lastNum:
incList.append(tempList)
tempList.pop()
lastNum=tempList[-1]
#############################################
elif lastNum < element:
tempList.append(element)
continue
You can bundle this into a function:
def append_if_lower_else_pop_end_from_list_until_lower(l, num):
"""Add num to l if l[-1] < num, else pop() from l until"""
while l and l[-1] > num:
l.pop()
l.append(num)
# this is not strictly needed - lists are mutable so you are mutating it
# returning it would only make sense for chaining off it with other methods
return l
k = [3,5,7,9,11,13]
print(k)
append_if_lower_else_pop_end_from_list_until_lower(k, 10)
print(k)
append_if_lower_else_pop_end_from_list_until_lower(k, 6)
print(k)
append_if_lower_else_pop_end_from_list_until_lower(k, 10)
print(k)
append_if_lower_else_pop_end_from_list_until_lower(k, 10)
print(k)
append_if_lower_else_pop_end_from_list_until_lower(k, -10)
print(k)
Output:
[3, 5, 7, 9, 11, 13] # start
[3, 5, 7, 9, 10] # after adding 10
[3, 5, 6] # after addding 6
[3, 5, 6, 10] # after adding 10
[3, 5, 6, 10, 10] # after adding 10 again
[-10] # after adding -10
Why return the list as well: example for chaining:
k = [3,5,17,9,11,13]
append_if_lower_else_pop_end_from_list_until_lower(k, 10).sort()
print(k)
Output:
[3, 5, 9, 10, 17]
Try this out:
yourlist = [3,1,4]
n = 1
resultlist = yourlist[:-1] if yourlist[-1]>=n else yourlist+[n]
print(resultlist)
n = 5
resultlist = yourlist[:-1] if yourlist[-1]>=n else yourlist+[n]
print(resultlist)
Output:
[3,1]
[3,1,4,5]
for n in range(1,1000000):
print(n)
result = []
for x in range(1,3000001):
if n%2==0:
x=n/2
else:
x=3*n+ 1
n=x
result.append(n)
if n==1:
break
print(len(result))
n+=1
I want these results to be printed in an array or something like that.I mean like this.
3,1,7,2,5,8,1,..
Then I want to take the highest element and its index.How can I do that?Thank you.
You can use str.join for the first task:
>>> result = [4, 0, 9, 7, 8, 3, 2, 6, 1, 5]
>>> print (', '.join(map(str, result)))
4, 0, 9, 7, 8, 3, 2, 6, 1, 5
And max with enumerate for the second task:
>>> ind, val = max(enumerate(result), key=lambda x:x[1])
>>> ind, val
(2, 9)
If you separate out the loop that does the work into its own function, this becomes much easier.
def collatz_length(n):
result = []
for x in range(1,3000001):
if n%2==0:
x=n/2
else:
x=3*n+ 1
n=x
result.append(n)
if n==1:
break
return len(result)
print(max((collatz_length(i + 1), i) for i in range(1000000)))
Since you're not using result, just its length, you could simplify (and speed up) the function a little by simply counting
You can tidy up the calculation of x by using a ternary expression
def collatz_length(n):
for c in range(1, 3000001):
x = 3 * n + 1 if n % 2 else n / 2
n = x
if n == 1:
return c