Get indices of elements in a list that satisfies certain sum value - python

I tried to get the indices of elements in a list, which summed of the value equal to certain number.
a = [50, 50, 50, 50, 75, 75]
b = 125
in the example above, I am looking for indices of element in list a that summed values equal to b (=125). indices combination that I am looking for is [0, 4], corresponding to the first number 50 and the first number 75.
I found a way by first creating possible combinations of the element in list a using itertools.combinations and then filter all combination that summed value equal to 125. it leads to indices [0,4], [1,4], [2,4],... This is quite problematic for list a that has many elements.
is there any simple way in python?
thank you.

Try this:
li = []
for i,j in enumerate(a):
for z,x in enumerate(a):
if int(x)+int(j) == int(b) and i>z:
li.append([i,z])

Related

Python: How to extract the index of the smallest value in a subset of a list?

I have a list L containing 100 values.
I wish to find the index (i.e., argmin) of this list between 20 to 100, so I write
print(np.argmin(L[20:]))
To my surprise, it printed out 0, instead of something that is equal or greater than 20.
What am I doing wrong?
argmin will return the index of the smallest element of the array passed; however, because this array starts at 20, you will need to add that starting point of your sublist, to obtain the index of the same smallest element in the original array:
start = 20
print(np.argmin(L[start:]) + start)

Converting numeric list in python to text based list

How can I convert a python list like:
[0, 1/4, 2/4, 3/4 , 4/4]
into the following:
[r'$25^{th}$', r'$50^{th}$', r'$75^{th}$', r'$100^{th}$']
Here each element of the 2nd list corresponds to a percentile value E.g. in the first list the element 0 corresponds to values below the 25th percentile. I want the solution to be easily extendible to different lengths e.g. current list has 5 elements, but we could have 2 elements or 10. Is there a pythonic way to do this?
Something like this I guess:
a = [0, 1/4, 2/4, 3/4 , 4/4]
b = [r'$%i^{th}$' % (i*100) for i in a[1:]] #skips first value
Lists have a function called list.extend(seq) which can dynamically extend your list with a sequence. For example:
l = [1,2,3,4]
l.extend([5,6])
print(l) # [1,2,3,4,5,6]
Now, to answer your actual question:
perclist = ["%4.2f th" % (float(i)*100) for i in fraclist]

How to slice an array with loop and apply operations to them? [closed]

mainArray=np.linspace(1,50,50)
##group1 is first 10 elements of mainArray
group1=np.array(1,2,3...10)
group2=np.array(11,12,13...20)
group3=np.array(21,22,23...30)
.
.
group5=np.array(41,42,43,44,45,46,47,48,49,50)
#i need to find standart deviation and mean value of these groups
#like np.mean(group1) and np.std(group1) for all groups
#then i have to calculate (group1-meanOfGroup1)/stdOfGroup1 for all groups
#and append it to one list or array.
I dont know how can i solve this with loops because my main problem is i can't make a loop that slices mainArray to groups and apply np.mean and np.std.
Acording to your last comment, you can do something like this:
# create a list whith values [1,2, ..., 100]
a = list(range(1, 101))
# Sum values by range of 3 values using list comprehension
final = [sum(a[k:k+3]) for k in range(0, len(a), 3)]
print(final)
Output:
[6,
15,
24,
33,
42,
51,
60,
...
267,
276,
285,
294,
100]
PS: The last sum is equal to 100 because groupping elements between 1 to 100 by 3 values will group them like this: 1->3, 4->6, ..., 94->96, 97->99, and the final element will be only one number which is 100
Edit:
An implementation of your last edit using list slicing like below.
For example:
a = np.linspace(1,50,50)
# unpacking groups
group1, group2, group3, group4, group5 = [a[k:k+10] for k in range(0, len(a), 10)]
# Applying: np.mean() to the groups
print(np.mean(group1))
print(np.mean(group2))
print(np.mean(group3))
print(np.mean(group4))
print(np.mean(group5))
Output:
5.5
15.5
25.5
35.5
45.5
oc=np.linspace(1,100,100)
ocmean= [np.mean(oc[k:k+25]) for k in range(0,len(oc),25)]
ocstdev=[np.std(oc[k:k+25]) for k in range(0,len(oc),25)]
## this 2 loops works, i got ocmean and ocstdev.
d=[(oc[k:k+25]-ocmean[i])/ocstdev[i] for k in range(0,len(oc),25) for i in range(len(ocmean))]
## This "d" doesnt gives what i want. It gives a list with 16*25 elements.
ocmean= [np.mean(oc[k:k+25]) for k in range(0,len(oc),25)]
ocstdev=[np.std(oc[k:k+25]) for k in range(0,len(oc),25)]
d=[]
i=0
k=0
while i <len(ocmean):
m=(oc[k:k+25]-ocmean[i])/ocstdev[i]
i=i+1
k=k+25
d.append(m)
Solved like this

Python: subset of list as equally distributed as possible?

I have a range of possible values, for example:
possible_values = range(100)
I have a list with unsystematic (but unique) numbers within that range, for example:
somelist = [0, 5, 10, 15, 20, 33, 77, 99]
I want to create a new list of length < len(somelist) including a subset of these values but as equally distributed as possible over the range of possible values. For example:
length_newlist = 2
newlist = some_function(somelist, length_newlist, possible_values)
print(newlist)
Which would then ideally output something like
[33, 77]
So I neither want a random sample nor a sample that chosen from equally spaced integers. I'd like to have a sample based on a distribution (here an uniform distribution) in regard to an interval of possible values.
Is there a function or an easy way to achieve this?
What about the closest values of your subset to certain list's pivots? ie:
def some_function(somelist, length_list, possible_values):
a = min(possible_values)
b = max(possible_values)
chunk_size = (b-a)/(length_list+1)
new_list = []
for i in range(1,length_list+1):
index = a+i*chunk_size
new_list.append(min(somelist, key=lambda x:abs(x-index)))
return new_list
possible_values = range(100)
somelist = [0, 5, 10, 15, 20, 33, 77, 99]
length_newlist = 2
newlist = some_function(somelist, length_newlist, possible_values)
print(newlist)
In any case, I'd also recommend to take a look to numpy's random sampling functions, that could help you as well.
Suppose your range is 0..N-1, and you want a list of K<=N-1 values. Then define an "ideal" list of K values, which would be your desired distribution over this full list (which I am frankly not sure I understand what that would be, but hopefully you do). Finally, take the closest matches to those values from your randomly chosen greater-than-K-length sublist to get your properly distributed K-length random sublist.
I think you should check random.sample(population, k) function. It samples the population in k-length list.

How to arrange three lists in such a way that the sum of corresponding elements if greater then appear first?

I am new in python. I have three lists of floats of same length. The numbers are randomly distributed in all lists. But the positions of elements in one list corresponds to the other elements of the same positions in other lists. Let's say the lists are,
a=[1,5,3,2,4]
b=[20,30,50,40,10]
c=[400,500,100,300,200]
Now, elements of same positions in these three lists correspond each other. Like 1, 20 and 400 correspond each other; 3, 50 and 100 correspond each other and so on.
I have to arrange the numbers in such a way that for any position i of these three lists if the sum of the corresponding numbers are greater then those three numbers should appear first in the lists. Like,
e=[500, 400, 300, 200, 100]
f=[30,20,40,10,50]
g=[5,1,2,4,3]
So the positions of corresponding numbers have changed altogether. Or their correspondence MUST NOT BREAK. As a beginner I have tried in many ways but all in vain. Please help me.
As an answer to the original question (pre edit)
Try this.
a=[1,5,3,2,4]
b=[20,30,50,40,10]
c=[400,500,100,300,200]
x = sorted(zip(a,b,c), key=lambda x: sum(x), reverse=True)
e, f, g = map(list, zip(*x))
print e
print f
print g
Output
[5, 1, 2, 4, 3]
[30, 20, 40, 10, 50]
[500, 400, 300, 200, 100]
Use zip to create a list of tuples, then sort them using their sum as the key, reversed so the largest sum is first. If you are using python 2.7 you could use izip instead of zip to somewhat reduce the memory burden with large lists but the full sorted list still needs to be created. In python 3 zip is equivalent of 2.7's izip.
The sorted function will return you list of tuples, so you want to now turn them back into your original 3 list format. The fastest and cleanest way to do this (courtesy of #JohnClements).
e, f, g = map(list, zip(*x))
To explain this statement, remembering that x is a list of tuples each of length 3.
First pass zip the unpacked tuples from x (using expression *x). This results in a new list containing 3 tuples. The first tuple contains all the first elements from the tuples in x, the second tuple contains all the second elements from x and so on.
Now you have a list of tuples, but we want our iterable to contain lists, so map is the correct function to use to do the conversion. It will be fast as its performing the conversion in native c code. The result is a list of lists.
finally we can unpack the list of lists to 3 separate list variables e, f and g.
If you require more detailed understanding of the code I suggest you print the output at intermediate stages.
You can sort the values of lists as:
a=[1,5,3,2,4]
b=[20,30,50,40,10]
c=[400,500,100,300,200]
x = sorted(range(len(a)), key = lambda x:a[x]+b[x]+c[x], reverse = True)
print "\n".join([" ".join([str(j[i]) for i in x])for j in [a, b, c]])
>>> 5 1 2 4 3
30 20 40 10 50
500 400 300 200 100

Resources