Home > Blockchain >  Finding x numbers in list greater than 0 with potential duplicates and assigning index of original l
Finding x numbers in list greater than 0 with potential duplicates and assigning index of original l

Time:02-10

I have lists of floats which will have some zeros in it. Eg.

numbers = [1.2, 0.0, 0.0, 1.2, 2.0, 2.5, 17, 1.3, 1.8, 1.3, 1.2]

I am trying to assign these values to n numbers (assuming it will be the first 5) for the lowest 5 values that are greater than 0.

I can get the first by using:

first = min(o for o in numbers if o > 0)

But as there are duplicates in the smallest value (1.2), I cannot easily assign second, third, fourth and fifth.

I need to assign these and allow me to keep the index of their values in the original list and assign these too. Eg.

first_pos = numbers.index(first)

I cannot use the above for second as it will assign it the first index value.

Is there any efficient way using a for loop or list comprehension or even a small function to assigning the other numbers so that:

second = 1.2
second_pos = 4
third = 1.2
third_pos = 10
fourth = 1.3
fourth_pos = 7
fifth = 1.3
fifth_pos = 9

I cannot do this with any list comprehension I know of for second as it will not pick up a duplicate. Eg.:

sec = min(o for o in numbers if o > first)

The lists vary in length of values (at least 5, though) and may or may not have duplicates and zeros but many will.

CodePudding user response:

Ok, to badly answer my own question, I have been able to do this by copying and removing the zeros, enumerating over the list for the index values and removing each number once assigned:

number = [n for n in numbers if n > 0]
numbs = [n for n, x in enumerate(numbers) if x > 0]
for n in number:
  first = min(number)
  first_pos = number.index(first)
  first_ind = numbs[first_pos]
number.remove(first)
numbs.remove(first_ind)
for n in number:
  second = min(number)
  sec_pos = number.index(second)
  sec_ind = numbs[sec_pos]
number.remove(second)
numbs.remove(sec_ind)

This will keep and assign the values and indexes of each minimum value greater than zero.

Is there any way to add this into a function to assign all values greater than zero in the list to its own variables?

CodePudding user response:

IIUC, one way using sorted with enumerate:

sorted(((n, i) for n, i in enumerate(numbers) if i > 0), key=lambda x: x[1])[:5]

Output of (index, value) pairs of first 5 smallest values:

[(0, 1.2), (3, 1.2), (10, 1.2), (7, 1.3), (9, 1.3)]
  • Related