Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning first occurrence index of a number in a list

Tags:

python

I have a bunch of csv files containing time data and numbers, I wrote a function to return the first occurrence of a number below a threshold (x) this way :

def bounce(tickList,x):
    n = 0
    for i in tickList:
        if float(i[1]) < x:
            return n
            break
        n += 1

except that when I loop the execution of the bounce function this way :

for i in os.listdir(resultDir):

    if "csv" in i:
        csvFile = resultDir+i
        print csvFile
        with open(csvFile, 'rb') as f:
            reader = csv.reader(f)
            tickList = []
            for line in reader:
                tickList.append(line)

        print bounce(tickList,5)

it keeps on returning zero (even though the first value is above the threshold ) .

Where am I going wrong ?


Here is a sample of one of the csv files :

1373289767.454535,9.9
1373289769.728528,9.9
1373289771.817576,9.9
1373289773.813036,11.7
1373289775.810985,11.7
1373289777.769641,11.7
1373289779.783134,12.2
1373289781.774255,11.8
1373289783.799892,12.0
1373289785.812967,11.4
1373289787.816991,11.4
1373289789.790835,11.3
1373289791.811245,10.9
1373289793.880356,10.8
1373289795.846866,10.7
1373289797.847552,10.6
1373289799.858929,10.6

Thanks in advance .

EDIT after comments

Here is the new function:

def bounce(tickList,x):
    n = 0
    for i in tickList:
        if float(i[1]) < x:
            return n 
        n += 1

if I print float(i[1]) it returns the right numbers so it is calling the right files .

SECOND EDIT

found the problem, the "level" I was feeding it was in fact a str and not an int, thanks for everybody who had a look and helped .

like image 999
Finger twist Avatar asked Jul 19 '13 19:07

Finger twist


1 Answers

I strongly suspect that your indentation is incorrect, and by mixing spaces and tabs Python interprets your method as:

def bounce(tickList,x):
    n = 0
    for i in tickList:
        if float(i[1]) < x:
            return n
            break
    n += 1

where n += 1 is left outside the loop and never increments n. Alternatively, n += 1 could be indented too far:

def bounce(tickList,x):
    n = 0
    for i in tickList:
        if float(i[1]) < x:
            return n
            break
            n += 1

Your function would return 0 for any case where there is a row with float(i[1]) below x.

You can test for such problems by running your script with python -tt scriptname.py, where -tt tells python to look for inconsistent use of tabs and spaces and raise an error if it finds such problems.

You can simplify your code by using enumerate(), and inlining the test, exiting reading the file early:

for fname in os.listdir(resultDir):
    if "csv" in fname:
        csvFile = os.path.join(resultDir, fname)
        print csvFile
        with open(csvFile, 'rb') as f:
            reader = csv.reader(f)
            for i, row in enumerate(reader)
                if float(row[1]) < 5:
                    print i
                    break    # exit for loop, continue with next file

The inner for loop can be simplified down further by using next() and an generator expression:

with open(csvFile, 'rb') as f:
    reader = csv.reader(f)
    print next((i for i, r in enumerate(reader) if float(r[1]) < 5), 'Not found')

as next() stops looping once a result has been found.

like image 56
Martijn Pieters Avatar answered Oct 31 '22 17:10

Martijn Pieters