For loop issue? - python

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

Related

Appending values of list with set condition

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]

how to find multiple non-repeating numbers in python?

I have a below method that finds the non-repeating elements in a list:
def dupes(a):
s = {}
for ele in a:
if ele not in s:
s[ele] = 1
else:
s[ele] += 1
for x in s:
if s[x] == 1:
return 'this is the only non-repeating element value is :', s[x], 'and the key is :', x
return
l = [4, 7, 4, 5, 7, 6, 5, 6, 10]
cd = dupes(l)
print("This is dupes: ", cd)
The code runs successfully and below is the output:
This is dupes: ('this is the only non-repeating element value is :', 1, 'and the key is :', 10)
But when I am trying to add more than one non-repeating elements in the list, the output doesn't change. For example, if I add 11 at the end of the list the output still remains the same as above..
Any idea?
Actually when you return at the 10th line, the function ends. This is in case you don't understand the list comprehension yet, as many have given you the solution with that technique. I will just give you a simple solution where it will return a list of non-repeating numbers.
def dupes(a):
s = {}
non_dupes = []
for ele in a:
if ele not in s:
s[ele] = 1
else:
s[ele] += 1
for x in s:
if s[x] == 1:
non_dupes.append(x)
return non_dupes
l = [4, 7, 4, 5, 7, 6, 5, 6, 10, 11]
cd = dupes(l)
print("This is dupes: ", cd)
def dupes(a):
s = {}
for ele in a:
if ele not in s:
s[ele] = 1
else:
s[ele] += 1
count = 0
keys = []
for x in s:
if s[x] == 1:
count += 1
keys.append(x)
return 'this is the only non-repeating element value is :', count, 'and the key is :', keys
That would be fine.
You can get all keys whose value is 1 using a list comprehension.
nondupes = [k for (k,v) in s.items() if v==1]
return 'Non-repeating elements: ' + str(nondupes)
Also, you could replace all your counting code with a collections.Counter:
s = Counter(a)
You can easely solve this in one line of python code, using the count() function:
l = [4, 7, 4, 5, 7, 6, 5, 6, 10 ,11]
only_one_time = [e for e in l if l.count(e) < 2]
print(only_one_time)
The given code returns the first non-repeating element it encounters.
For example,
if the input list is l = [12, 11, 4, 7, 4, 5, 7, 6, 5, 6, 10],
the output would be This is dupes: ('this is the only non-repeating element value is :', 1, 'and the key is :', 12).
You can succinctly achieve the above with Counter:
from collections import Counter
l = [4, 7, 4, 5, 7, 6, 5, 6, 10]
c = Counter(l)
dupes = list(key for key in c if c[key] > 1)
print("This is dupes: ", dupes)
Output:
This is dupes: [4, 7, 5, 6]
The issue that you are encountering is that you are returning prematurely from your function with a string containing the first duplicate. The rest of the duplicates are lost.
You already have the list of duplicates, let's return just the data so we can separate the calculation of results from the display of results.
return list(e for e in s if s[e] > 1)

How to cumsum all values at tuple index n, from a list of tuples?

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]

Conditional checking between two int objects

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]

Python lists (getting triplets of identical numbers from the list)

Assume I have a list [12,12,12,12,13,13,13,13,14,14,14,14,14,14,14,15,15,15, etc]
I would like my result to be the following:
[12,12,12,13,13,13,14,14,14,15,15,15]
The number of identical numbers in the first list can vary, but I want to get triplets for each range of the identical numbers. I assume I could iterate through the list starting from the first number (12) and get the first 3 identical numbers (12,12,12), and then compare the numbers and once the number 12 changes to 13, get the next 3 numbers (13,13,13), and so on. But I cannot think of a good approach to do it correctly. Thank you for any suggestions.
I would use itertools.groupby() to isolate the strings of identical numbers, then use a list comprehension to create the triplets:
import itertools
some_list = [12,12,12,12,13,13,13,13,14,14,14,14,14,14,14,15,15,15,]
updated_list = [i for k,_ in itertools.groupby(some_list) for i in [k]*3]
assert updated_list == [12,12,12,13,13,13,14,14,14,15,15,15]
updated_list = []
curr_number = some_list[0]
curr_count = 0
for n in some_list:
if n == curr_number
curr_count += 1
if not (curr_count > 3):
updated_list.append(n)
else:
curr_number = n
curr_count = 1
updated_list.append(n)
Seems as a set approach is a bit faster than itertools. If you need it sorted, less but still faster.
A = [12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15]
def with_set(A):
A = set(A)
return list(A) * 3
import itertools
def with_iter(A):
return [i for k,_ in itertools.groupby(A) for i in [k]*3]
import timeit
print("Result with set: ", timeit.timeit(lambda:with_set(A),number = 1000))
print("Result with iter: ", timeit.timeit(lambda:with_iter(A),number = 1000))
Result with set: 0.008438773198370306
Result with iter: 0.018557160246834882
Below line of code is self explanatory:
A = [1, 2, 3, 4, 1, 4]
A = list(set(A)) #removes duplicates
A *= 3 #multiplies the unique list 3 times
print sorted(A) # makes a new sorted list

Categories

Resources