Reputation: 845
I have two list underdraw
and rate
. They both contain 20 elements.
underdraw = [0,20,23,0,23,0,0,0,55,4,3,10,0,0,0,0,23,45,56,0]
rate = [0,201,43,0,123,0,0,0,0,43,35,120,0,0,0,0,253,5,0,0]
I divided the underdraw list into two lists further underLimit
and beyondLimit
and the limit is 25
.
underLimit = [i if i <= 25 else 0 for i in underdraw]
beyondLimit = [i if i > 25 else 0 for i in underdraw]
now I combined these two lists with the rate
combinedLimits1 = list(zip(underLimit, rate))
combinedLimits2 = list(zip(beyondLimit, rate))
Now there are 20 tuples inside these two lists combinedList1
and combinedList2
. I want to catogorized them into 5 sets.
n = 5
x = [combinedLimits1[i:i + n] for i in range(0, len(combinedLimits1), n)]
y = [combinedLimits2[i:i + n] for i in range(0, len(combinedLimits2), n)]
If you print the blocks of x and y
x=[(0, 0), (20, 201), (23, 43), (0, 0), (23, 123)]#list1
[(0, 0), (0, 0), (0, 0), (0, 0), (4, 43)]#list2
[(3, 35), (10, 120), (0, 0), (0, 0), (0, 0)]#list3
[(0, 0), (23, 253), (0, 5), (0, 0), (0, 0)]#list4
y=[(0, 0), (0, 201), (0, 43), (0, 0), (0, 123)]#list1
[(0, 0), (0, 0), (0, 0), (55, 0), (0, 43)]#list2
[(0, 35), (0, 120), (0, 0), (0, 0), (0, 0)]#list3
[(0, 0), (0, 253), (45, 5), (56, 0), (0, 0)]#list4
Now I want to sort this x
and y
in increasing rate order and took the smallest 3 values from it and take only those values in comparison when THERE IS A VALUE IN UNDERDRAW.
Expected output(for x):
Smallest 3 rates(if there is no rate then just put 20 there)
[(23,43), (23, 123), (20, 201)]#list1
[(4,43), (0, 20), (0, 20)]#list2
[(3,35), (10, 120), (0, 20)]#list3
[(23,253), (0, 20), (0, 20)]#list4
y=
[(0, 20), (0, 20), (0, 20)]#list1
[(50, 0), (0, 20), (0, 20)]#list2
[(0, 20), (0, 20), (0, 20)]#list3
[(56, 0), (45, 5), (0, 20)]#list4
So basically it is sorting only when there is a value in underdraw and as I required 3 min values so, if there are no min 3 elements then just simple put rate = 20 there. Can someone please help?
Upvotes: 1
Views: 88
Reputation: 42492
now I combined these two lists with the rate
combinedLimits1 = list(zip(underLimit, rate)) combinedLimits2 = list(zip(beyondLimit, rate))
Are you sure that makes sense? Since underdraw
and rate
are the same lengths I'd have assumed they matched, this is going to combine the first n rates with what's under the limit, and the first k rates with above (where n and k are the number of items respectively under and above the limit).
Now there are 20 tuples inside these two lists combinedList1 and combinedList2. I want to catogorized them into 5 sets.
That's just chunking though, not categorisation.
Now I want to sort this x and y in increasing rate order and took the smallest 3 values from it and take only those values in comparison when THERE IS A VALUE IN UNDERDRAW. Expected output(for x): Smallest 3 rates(if there is no rate then just put 20 there)
So... take the first 3 items with a non-zero underdraw (they all have a value) ordered by ascending rate, pad with (0, 20)
to 3 items if necessary?
# remove entries with underdraw = 0, sort by rate
items = sorted(((d, r) for d, r in lst if d != 0), key=lambda item: item[1])
# we now have 0~5 items, cut down to size
items = items[:3]
# pad with however many (0, 20) items are missing to go to 3
items += [(0, 20)] * (3 - len(items))
Upvotes: 1
Reputation: 1077
# Code (edited) from geeksforgeeks.org/python-program-to-sort-a-list-of-tuples-by-second-item/
def sortTuple(tup):
tup.sort(key = lambda i: i[1])
return tup
# You can repeat this same thing for the y list
for index, sublist in enumerate(x):
orderedSublist = sortTuple(sublist)
for element in orderedSublist.copy():
if element[1] == 0:
orderedSublist.append(orderedSublist.pop(0))
orderedSublist[-1] = (orderedSublist[-1][0], 20) # You can't mutate (edit) tuples so we create a new one
orderedSublist = orderedSublist[:3] # Taking the smallest 3 elements (excluding 0s)
x[index] = orderedSublist
The code is essentially going through every sublist in x and sorting that according to the second element of the tuple. This is sorted in a way that the 0s come at the beginning as well so we go through every element in the ordered list and shift all the tuples with the rate being 0 to the back.
Finally, we just take the first 3 elements and print out the list.
Upvotes: 1
Reputation: 6483
You could try this with filter
and sorted
:
underdraw = [0,20,23,0,23,0,0,0,55,4,3,10,0,0,0,0,23,45,56,0]
rate = [0,201,43,0,123,0,0,0,0,43,35,120,0,0,0,0,253,5,0,0]
underLimit = [i if i <= 25 else 0 for i in underdraw]
beyondLimit = [i if i > 25 else 0 for i in underdraw]
combinedLimits1 = list(zip(underLimit, rate))
combinedLimits2 = list(zip(beyondLimit, rate))
n = 5
x = [combinedLimits1[i:i + n] for i in range(0, len(combinedLimits1), n)]
y = [combinedLimits2[i:i + n] for i in range(0, len(combinedLimits2), n)]
newx=[sorted(list(filter(lambda y: y[0]!=0,ls)),key=lambda h: h[1]) for ls in x]
newx=[ls if len(ls)==3 else ls+[(0,20)]*(3-len(ls)) for ls in newx ]
newy=[sorted(list(filter(lambda y: y[0]!=0,ls)),key=lambda h: h[1]) for ls in y]
newy=[ls if len(ls)==3 else ls+[(0,20)]*(3-len(ls)) for ls in newy ]
print(newx)
print(newy)
Output:
newx
[[(23, 43), (23, 123), (20, 201)], [(4, 43), (0, 20), (0, 20)], [(3, 35), (10, 120), (0, 20)], [(23, 253), (0, 20), (0, 20)]]
newy
[[(0, 20), (0, 20), (0, 20)], [(55, 0), (0, 20), (0, 20)], [(0, 20), (0, 20), (0, 20)], [(56, 0), (45, 5), (0, 20)]]
Upvotes: 1