1

I have a CSV file filled with ticket information. I created a small script to input ticket numbers separated by spaces into a list which searches the CSV file for each ticket in the list, and if it finds the ticket, it outputs info on that row.

My problem is if I search for a ticket not in the CSV file, it just skips past it and moves on, but I would like it to tell me that that ticket is not in the file. From what I can tell, it's searching the CSV file by row or line. If I try an else statement, it will start printing out every line in the CSV file, if that ticket's not in the row.

I need to be able to input multiple ticket numbers and have python search each one individually. If it finds the ticket in column 1, then print information from that row and if it doesn't find the ticket in any rows column 1, then print out that ticket followed by "is not in the file".

import csv

file = csv.reader(open('Path To CSV file', "rb"), delimiter=",")
newticket = raw_input('Enter Ticket Numbers:').split()

for line in file:
    for tickets in newticket:
        if tickets == line[1]:
            print(tickets, line[36], line[37])
1
  • 1
    If your CSV's of a manageable size, I'd go with PM 2Ring's solution, it's more efficient than yours and is a very common method for doing this sort of thing in Python. If your file is too large to fit in memory, I'd look into databases. But that's outside the scope of this question, and unless your csv is gigabytes in size, should not be a problem. Commented May 4, 2018 at 17:33

1 Answer 1

3

If your CSV file isn't enormous, I suggest reading the whole thing, extracting the data you want into a dictionary, with the ticket number as the key. Searching a dict is very fast.

I've modified your file opening code to use the with statement, which fails gracefully if there's a problem reading the file. BTW, there's no need to specify the comma as the CSV delimiter, since that the default delimiter.

import csv

with open('Path To CSV file', "rb") as f:
    data = {line[1]: (line[36], line[37]) for line in csv.reader(f)}

newtickets = raw_input('Enter Ticket Numbers:').split()

for ticket in newtickets:
    line = data.get(ticket)
    if line:
        print(ticket, line)
    else:
        print(ticket, "not found")

The dict.get method returns None if the key isn't in the dict, although you can specify another default return value if you want. So we could re-write that part like this:

for ticket in newtickets:
    line = data.get(ticket, "not found")
    print(ticket, line)

Alternatively, we could use the in operator:

for ticket in newtickets:
    if ticket in data:
        print(ticket, data[ticket])
    else:
        print(ticket, "not found")

All 3 versions have roughly the same efficiency, choose whichever you feel is the most readable.

Sign up to request clarification or add additional context in comments.

7 Comments

I agree, though where you used if line, I would use if line is not None as if the value in the dictionary is falsey, it will fail the check even though the value was found. I think it's fair to make the assumption that the value in the dictionary's not None (if it is you'll probably want to just access the value and catch any exceptions), but it could very well be Falsey in many situations (e.g. having value 0).
@SandeepDcunha You had me worried there for a moment. :) But the values in the dict are all 2-tuples, so it's impossible for them to be falsey. The only falsey tuple is the empty tuple ().
True, though since it's a number it would be very sensible to cast it to an int in which case it could very well have value 0. Also, if someone wants to adapt this code for another situation, they could run into this issue. When comparing for None and not general truthiness, it's best to do the explicit comparison is not None. I agree that your code would work perfectly fine in this scenario, but this is a possible pitfall it could encounter with slight adaptions to the code by OP or anyone else using it.
@SandeepDcunha But we aren't looking at the ticket number (which could very well be an alphanumeric "number"), we're looking at the tuple of (line[36], line[37]) from the CSV file. However, I will agree that in many cases it is better to use if x is not None: rather than simply if x:
@SandeepDcunha Personally, I'd probably use the line = data.get(ticket, "not found") version. It's the most compact, and that way the None issue doesn't arise.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.