Finding calculation value in python list - python

I have a python list like this.
[100, 150, 30, 50, 10, 20, 40]
Then I want to find 90 in list above (yes of course not in there), but my expected result are:
[50, 40]
or
[50, 30, 10]
How can I achieve that in python or other programming language?

You can use a list comprehension to iterate over all the combinations of the list elements that sum to your target value
>>> from itertools import combinations
>>> data = [100, 150, 30, 50, 10, 20, 40]
>>> target = 90
>>> [comb for n in range(1, len(data)+1) for comb in combinations(data, n) if sum(comb) == target]
[(50, 40), (30, 50, 10), (30, 20, 40)]

for this, you need to check each combination of numbers. for example:
take 100 and check if its less than 90, if yes, then check it with every other number less than 90 and see if they add to 90, but, if both numbers add to less than 90, check with the other numbers to see if the again add to 90.

Try using a list-comprehension and set:
>>> set([x for x in lst for y in lst if x+y == 90 and x != y])
{40, 50}

Related

How to find the smallest threshold from one list to fit another list

I have two lists of marks for the same set of students. For example:
A = [22, 2, 88, 3, 93, 84]
B = [66, 0, 6, 33, 99, 45]
If I accept only students above a threshold according to list A then I can look up their marks in list B. For example, if I only accept students with at least a mark of 80 from list A then their marks in list B are [6, 99, 45].
I would like to compute the smallest threshold for A which gives at least 90% of students in the derived set in B getting at least 50. In this example the threshold will have to be 93 which gives the list [99] for B.
Another example:
A = [3, 36, 66, 88, 99, 52, 55, 42, 10, 70]
B = [5, 30, 60, 80, 80, 60, 45, 45, 15, 60]
In this case we have to set the threshold to 66 which then gives 100% of [60, 80, 80, 60] getting at least 50.
This is an O(nlogn + m) approach (due to sorting) where n is the length of A and m is the length of B:
from operator import itemgetter
from itertools import accumulate
def find_threshold(lst_a, lst_b):
# find the order of the indices of lst_a according to the marks
indices, values = zip(*sorted(enumerate(lst_a), key=itemgetter(1)))
# find the cumulative sum of the elements of lst_b above 50 sorted by indices
cumulative = list(accumulate(int(lst_b[j] > 50) for j in indices))
for i, value in enumerate(values):
# find the index where the elements above 50 is greater than 90%
if cumulative[-1] - cumulative[i - 1] > 0.9 * (len(values) - i):
return value
return None
print(find_threshold([22, 2, 88, 3, 93, 84], [66, 0, 6, 33, 99, 45]))
print(find_threshold([3, 36, 66, 88, 99, 52, 55, 42, 10, 70], [5, 30, 60, 80, 80, 60, 45, 45, 15, 60]))
Output
93
66
First, define a function that will tell you if 90% of students in a set scored more than 50:
def setb_90pc_pass(b):
return sum(score >= 50 for score in b) >= len(b) * 0.9
Next, loop over scores in a in ascending order, setting each of them as the threshold. Filter out your lists according that threshold, and check if they fulfill your condition:
for threshold in sorted(A):
filtered_a, filtered_b = [], []
for ai, bi in zip(A, B):
if ai >= threshold:
filtered_a.append(ai)
filtered_b.append(bi)
if setb_90pc_pass(filtered_b):
break
print(threshold)

Python find pairs of socks from a list

I'm pretty new to programming and python. I was asked to find out a pair of socks from a given list of numbers.
My question was - "There is a large pile of socks that must be paired by color. Given an array of integers representing the color of each sock, determine how many pairs of socks with matching colors there are."
Sample Input
STDIN Function
----- --------
9 n = 9
10 20 20 10 10 30 50 10 20 ar = [10, 20, 20, 10, 10, 30, 50, 10, 20]
Sample Output
3
So my logic was pretty simple, iterate through the list, take a number, compare it with others. If two same numbers are found, count them as a pair and remove them from the list. Then do the same untiil none are left
# Complete the sockMerchant function below.
def sockMerchant(n, ar):
print(ar)
l=[]
result=0
for i in ar:
a=i
c=0
print("a",a)#line for checking
ar.remove(i)
l=ar
print("ar",ar)#line for checking
print("l", l)#line for checking
for j in l:
f=l.index(j)
print("index", f))#line for checking
print("j",j))#line for checking
if j == a:
c=c+1
print("c",c))#line for checking
ar.remove(j)
print("ar2",ar))#line for checking
result=c/2
print("c2",c))#line for checking
return result
n=9
ar=[10, 20, 20, 10, 10, 30, 50, 10, 20]
sockMerchant(n, ar)
Please ignore the line of code beside the comments. They are just there to see the control flow. and here is my output:
[10, 20, 20, 10, 10, 30, 50, 10, 20]
a 10
ar [20, 20, 10, 10, 30, 50, 10, 20]
l [20, 20, 10, 10, 30, 50, 10, 20]
index 0
j 20
index 0
j 20
index 2
j 10
c 1
ar2 [20, 20, 10, 30, 50, 10, 20]
index 3
j 30
index 4
j 50
index 2
j 10
c 2
ar2 [20, 20, 30, 50, 10, 20]
a 20
ar [20, 30, 50, 10, 20]
l [20, 30, 50, 10, 20]
index 0
j 20
c 1
ar2 [30, 50, 10, 20]
index 1
j 50
index 2
j 10
index 3
j 20
c 2
ar2 [30, 50, 10]
a 10
ar [30, 50]
l [30, 50]
index 0
j 30
index 1
j 50
c2 0
Python is full of wonderful utils that can be helpful. Counters from collections can be used for counting how many socks of each color you got and then you just divide by 2 to get the number of pairs.
from collections import Counter
from typing import List
def sock_merchant(socks: List[int]) -> int:
counter = Counter(ar)
return sum((count // 2 for count in counter.values())
Initializing counter with an array will give you something that looks like
Counter({10: 4, 20: 3, 30: 1, 50: 1})
which is the value from the array (i.e color of the sock) and the number of times it occurs in the array.
Like with normal dicts, counters also have a .values() methods that will give you only the values, and since we want the number of pairs, we take the sum of the values after doing integer division on each of them.

how to insert 2 elements after each element in a for-loop on a list?

I need a list of coordinates to be extended by two new coordinates after each original coordinate in order to keep a "drawing" order.
I have read and understand that a simple loop will run into an infinite loop that is why I am using enumerate over the first list and insert/append to second list.
NOTE: 'lc' and 'rc' in the loop is used to test and show this!
coords=([100,100,10], [100,101,10], [100,102,10])
print (coords)
coords_n=[]
for idx,val in enumerate(coords):
print (idx,val)
coords_n.insert(idx, [val[0], val[1], val[2]])
lc= [val[0]-50, val[1], val[2]+40, 'lc']
coords_n.insert(idx+1,lc)
rc= [val[0]+50, val[1], val[2]+40, 'rc']
coords_n.insert(idx+2,rc)
print (coords_n)
The results are a list but in a wrong order with the new elements at the end of list.
new List:
0 [100, 100, 10]
1 [100, 101, 10]
2 [100, 102, 10]
3 [50, 102, 50, 'lc']
4 [150, 102, 50, 'rc']
5 [50, 101, 50, 'lc']
6 [150, 101, 50, 'rc']
7 [50, 100, 50, 'lc']
8 [150, 100, 50, 'rc']
Thus, 3 + 4 should be at position 1 +2 followed by 1 and 5+6 and so on.
I think you just meant to use append instead of insert
try this:
coords=([100,100,10], [100,101,10], [100,102,10])
print (coords)
coords_n=[]
for val in coords:
coords_n.append([val[0], val[1], val[2]])
lc= [val[0]-50, val[1], val[2]+40, 'lc']
coords_n.append(lc)
rc= [val[0]+50, val[1], val[2]+40, 'rc']
coords_n.append(rc)
print (coords_n)
Use list.append function instead of fiddling with insert and position
coords=([100,100,10], [100,101,10], [100,102,10])
coords_n=[]
for [x, y, z] in coords:
lc = [x - 50, y, z + 40, 'lc']
rc = [x + 50, y, z + 40, 'rc']
coords_n.append([x, y, z])
coords_n.append(lc)
coords_n.append(rc)
from pprint import pprint
pprint(coords_n)

Combine elements of two lists with if statement in python

I am trying to merge two lists depend on the criteria.
I have following codes.
R1=[10,20,30,40,50]
R2=[5,10,45,40,45]
for n,m in zip(R1,R2):
if n>m:
print(n)
else:
print(m)
When I run above code,the results is :
10
20
45
40
50
I don't know how to get that results as a new list like this:
results=[10,20,45,40,50]
How can I do this?
Thanks in advance.
You can use max and list comprehension.
result = [max(pair) for pair in zip(R1, R2)]
print result
Create a new list and append() the result:
In []:
R1=[10,20,30,40,50]
R2=[5,10,45,40,45]
results = []
for n, m in zip(R1,R2):
if n>m:
results.append(n)
else:
results.append(m)
results
Out[]:
[10, 20, 45, 40, 50]
You can look at a list comprehension to do the same thing:
In []:
results = [n if n>m else m for n, m in zip(R1, R2)]
results
Out[]:
[10, 20, 45, 40, 50]
Or even more simply:
In []:
results = [max(x) for x in zip(R1, R2)]
results
Out[]:
[10, 20, 45, 40, 50]
Functional solution
The map() and max() functions make short work of this problem:
>>> R1 = [10, 20, 30, 40, 50]
>>> R2 = [5, 10, 45, 40, 45]
>>> list(map(max, R1, R2))
[10, 20, 45, 40, 50]
List comprehension solution
Another technique to is to use a conditional expression in a list comprehension:
>>> [n if n>m else m for n, m in zip(R1, R2)]
[10, 20, 45, 40, 50]
R1=[10,20,30,40,50]
R2=[5,10,45,40,45]
temp_list = []
for n,m in zip(R1,R2):
if n>m:
temp_list.append(n)
else:
temp_list.append(m)
print(temp_list)
this should work.
you are trying to print each value, so it is printed on separate lines.
Use map with multiple iterables:
>>> R1=[10,20,30,40,50]
>>> R2=[5,10,45,40,45]
>>> it = map(max, R1, R2)
>>> print(list(it))
[10, 20, 45, 40, 50]
(Generally, the place to look is in the itertools module, but in this case the function is actually builtin).

Remove all occurrences of an integer from list

In python, how can I remove all occurrences of an integer from a list. For example:
list_a = [5, 20, 15, 10, 55, 30, 65]
list_a.METHOD(5)
print(list_a)
[20, 10, 30]
Essentially, the method removes anything that contains a 5. Not specifically multiples of 5, given that 10 and 20 do not contain a 5. Thanks.
list_a = [5, 20, 15, 10, 55, 30, 65]
list_a = [x for x in list_a if "5" not in str(x)]
print(list_a)
[20, 10, 30]
This is one way:
[x for x in list_a if str(x).find('5') < 0]
That's a list comprehension that converts each number to a string and then searches the string for the character 5. find returns -1 if not found so we keep only things where the 5 wasn't found.
You can use filter and lambda.
filter(lambda x:"5" not in str(x) , [5, 20, 15, 10, 55, 30, 65])

Categories