Finger twist
Finger twist

Reputation: 3786

Returning first occurrence index of a number in a list

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 .

Upvotes: 6

Views: 371

Answers (5)

Ma3x
Ma3x

Reputation: 6549

Make sure that you are not mixing spaces and tabs in the identation.

This works as expected for me (I edited the original function to return both the index and the element value).

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

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1121962

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.

Upvotes: 2

twil
twil

Reputation: 6162

You've sad you need a value below threshold and that's exactly what in your code. But after you are expecting value above threshold. Change bounce() or threshold ot test data:)

import csv

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

csvFile = 'test.csv'
print csvFile
tickList = []
with open(csvFile, 'rb') as f:
    reader = csv.reader(f)
    for line in reader:
        tickList.append(line)

print bounce(tickList,5)

This code prints 0.

Upvotes: 1

Jiminion
Jiminion

Reputation: 5168

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

something like this???

Upvotes: 0

Jon Clements
Jon Clements

Reputation: 142156

I'm not convinced you need the entire data into memory, so maybe something as simple as:

reader = enumerate(csv.reader(f))
idx, row = next((r for r in reader if float(r[1][1]) < 5), (None, None))

Upvotes: 0

Related Questions