-2

I'm trying to use min in a list that came from a .csv and some of the values are '' how can I ignore those and also "0"?

I tried

index1 = (life_expectancy.index(min(life_expectancy,)))
print(life_expectancy[index1])

and got nothing, when i tried:

index1 = (life_expectancy.index(min(life_expectancy, key=int)))

I got:

ValueError: invalid literal for int() with base 10: ''

Because this is the value that the function treats at the min

Hunter
  • 321
  • 2
  • 11
LuigiMopi
  • 19
  • 4

5 Answers5

2

I don't think there is a simple way to do this in a single line of code using min.

One way to avoid 0-values is to call filter before min. Then, to avoid invalid values, you can write a wrapper around int that returns 0 on invalid values.

def int_or_zero(s):
    try:
        return int(s)
    except ValueError:
        return 0

def nonzero_min(seq):
    return min(filter(None, map(int_or_zero, seq)))

print( nonzero_min(['hello', '0', '12', '3', '0', '5', '']) )
# 3

Another way is to write the whole function "manually" with a for-loop.

def nonzero_min2(seq):
    m = 9999999
    for x in seq:
        try:
            x = int(x)
            if x < m and x != 0:
                m = x
        except ValueError:
            pass
    return m

print( nonzero_min2(['hello', '0', '12', '3', '0', '5', '']) )
# 3
Stef
  • 13,242
  • 2
  • 17
  • 28
  • Hey Stef, thanks for the answer! I was trying to avoid the second solution. I also have not yet studied try-except yet, although I've ssen it around. Aprecciate the time you took to share it. – LuigiMopi Nov 23 '22 at 17:00
  • @LuigiMopi Yes, I also think it's a good idea to avoid the second method. Here the `try / except` is just to avoid crashing when testing `int('hello')` – Stef Nov 24 '22 at 08:48
1

The problem statement is incomplete, so we cannot conclude.

Is it a list of strings ? integers ? floats ? with None ? with float("NaN") ? a mix of all ?


With a list of mixed numbers and strings, you would have:

life_expectancy= [2,3,5,7,11,13, "", 0, "", 3.14, 1.414, "", 1.712, "", 1.618, 0]
index1 = (life_expectancy.index(min(life_expectancy,)))
TypeError: '<' not supported between instances of 'str' and 'int'

index1 = (life_expectancy.index(min(life_expectancy,key=int)))
ValueError: invalid literal for int() with base 10: ''

With a list of mixed numbers, None, and strings, you would have:

life_expectancy= [2,3,5,7,11,13, None, 0, None, 3.14, 1.414, None, 1.712, None, 1.618, 0]
index1 = (life_expectancy.index(min(life_expectancy,)))
TypeError: '<' not supported between instances of 'NoneType' and 'int'

index1 = (life_expectancy.index(min(life_expectancy,key=int)))
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'

So, yeah ... it all depends on your actual inputs... Stef's answer should do the trick.

otherwise:

life_expectancy= [2,3,5,7,11,13, "", "0", "", "3.14", 1.414, "", 1.712, "", 1.618, 0]
new_list = [e for e in life_expectancy if e and type(e) != str]
new_list
>>> [2, 3, 5, 7, 11, 13, 1.414, 1.712, 1.618]
  • revise your CSV loading.

you may consider using pandas and its read_csv() function, quopting:

Read a comma-separated values (csv) file into DataFrame.

Also supports optionally iterating or breaking of the file into chunks.

Give a special look to all the doc/parameters, because there are a lot of default values and inferences, especially:

sepstr, default ‘,’

Delimiter to use.

and:

decimalstr, default ‘.’

Character to recognize as decimal point (e.g. use ‘,’ for European data).

(and a lot more)

LoneWanderer
  • 3,058
  • 1
  • 23
  • 41
  • Thanks for answering. I'm kinda new to python and programing itself, but I'm pretty sure all the values of the list should be strings, since it's taken from the .csv and didn't have any kind of "treatment". Anyway, thanks for the tip, this will help me formulate better questions in the future. – LuigiMopi Nov 23 '22 at 16:56
  • I edited the answer to point you towards pandas.read_csv(). – LoneWanderer Nov 23 '22 at 17:02
  • 1
    @LuigiMopi If you load a csv file with python's standard `csv` module, then the data will be strings. But if you load it with [pandas.read_csv](https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html) or [numpy.loadtxt](https://numpy.org/doc/stable/reference/generated/numpy.loadtxt.html) it can be automatically converted to the type you want. – Stef Nov 24 '22 at 09:07
  • @Stef hence the "because there are a lot of [...] inferences" part ^^ – LoneWanderer Nov 24 '22 at 17:58
-1

Try this:

new_life_expectancy = [value for value in life_expectancy if value != '' and value != '0']

This removes all instances of '' and 0

Hunter
  • 321
  • 2
  • 11
-1

you can try something like :

df_temp = df.loc[df["column_name"]!=""]

df_temp = df_temp.loc[df_temp["column_name"]>0]

Im not sure if you could just do != "" | 0, not sure if loc supports double condition.

Then you can just do a min on that df_temp

Dava
  • 11
  • 4
-2
#You can simply remove all 0 terms and string terms from your list and then use min
l=[1,34,6,4,1,4,0]
l1=l
while True:
    try:
        l1.remove(0)
    except ValueError:
        break    
print(min(l1))   
  • Thanks Ammar! I'll try this one as well :D – LuigiMopi Nov 23 '22 at 16:57
  • 1
    Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes. – Mark Rotteveel Nov 24 '22 at 14:27