Richard Blakemore
Richard Blakemore

Reputation: 1

How do I use index iteration to search in a list in Python?

This is for an assignment which I've nearly finished. So the goal is to be able to search the list based on CID, which is the first value in each line of the txt file.

The text file contains the following records, and is tab delimited:

0001    001 --  --  1234.00 --  --  148.08  148.08  13.21   1395.29
0002    011 --  100.00  12000.00    --  5.00    1440.00 1445.00 414.15  13959.15
0003    111 100.00  1000.00 1000.00 8.00    50.00   120.00  178.00  17.70   2295.70
0004    110 1200.00 100.00  --  96.00   5.00    --  101.00  6.15    1407.15
0005    101 100.00  --  1300.00 8.00    --  156.00  164.00  15.60   1579.60
0006    100 1200.00 --  --  96.00   --  --  96.00   5.40    1301.40
0007    010 --  1500.00 --  --  75.00   --  75.00   2.25    1577.25
0008    001 --  --  1000.00 --  --  120.00  120.00  9.00    1129.00
0009    111 1000.00 1000.00 1000.00 80.00   50.00   120.00  250.00  28.50   3278.50
0010    111 100.00  10000.00    1000.00 8.00    500.00  120.00  628.00  123.90  11851.90

Text file can be found here.

I'm new to Python, and haven't got my head around it yet. I need to be able to somehow dynamically fill in lines[0] with other index positions. For example...'0002' is found in index [0], 0002 is found if I change to lines[1] and so forth. I've tried various whiles, enumerating, list-comprehension, but most of that is beyond my understanding. Or maybe there's an easier way to display the line for a particular 'customer'?

   with open('customer.txt', 'r') as file:

        for line in file:
            lines = file.read().split('\n')
    search = input("Please enter a CID to search for: ")

    if search in lines[0]:
        print(search, "was found in the database.")
        CID = lines[0]
        print(CID)
    else:
        print(search, "does not exist in the database.")

Upvotes: 0

Views: 194

Answers (3)

steveha
steveha

Reputation: 76695

Here's how I think you should solve this problem. Comments below the code.

_MAX_CID = 9999
while True:
    search = input("Please enter a CID to search for: ")
    try:
        cid = int(search)
    except ValueError:
        print("Please enter a valid number")
        continue
    if not 0 <= cid <= _MAX_CID:
        print("Please enter a number within the range 0..%d"% _MAX_CID)
        continue
    else:
        # number is good
        break

with open("customer.txt", "r") as f:
    for line in f:
        if not line.strip():
            continue # completely blank line so skip it
        fields = line.split()
        try:
            line_cid = int(fields[0])
        except ValueError:
            continue # invalid line so skip it

        if cid == line_cid:
            print("%d was found in the database." % cid)
            print(line.strip())
            break
    else:
        # NOTE! This "else" goes with the "for"!  This case
        # will be executed if the for loop runs to the end
        # without breaking.  We break when the CID matches
        # so this code runs when CID never matched.
        print("%d does not exist in the database." % cid)
  • Instead of searching for a text match, we are parsing the user's input as a number and searching for a numeric match. So, if the user enters 0, a text match would match every single line of your example file, but a numeric match won't match anything!

  • We take input, then convert it to an integer. Then we check it to see if it makes sense (isn't negative or too large). If it fails any test we keep looping, making the user re-enter. Once it's a valid number we break out of the loop and continue. (Your teacher may not like the way I use break here. If it makes your teacher happier, add a variable called done that is initially set to False, and set it to True when the input validates, and make the loop while not done:).

  • You seem a bit confused about input. When you open a file, you get back an object that represents the opened file. You can do several things this object. One thing you can do is use method functions like .readlines() or .read(), but another thing you can do is just iterate it. To iterate it you just put it in a for loop; when you do that, each loop iteration gets one line of input from the file. So my code sample sets the variable line to a line from the file each time. If you use the .read() method, you slurp in the entire file into memory, all at once, which isn't needed; and then your loop isn't looping over lines of the file. Usually you should use the for line in f: sort of loop; sometimes you need to slurp the file with f.read(); you never do both at the same time.

  • It's a small point, but file is a built-in type in Python, and by assigning to that you are rebinding the name, and "shadowing" the built-in type. Why not simply use f as I did in my program? Or, use something like in_file. When I have both an input file and an output file at the same time I usually use in_file and out_file.

  • Once we have the line, we can split it into fields using the .split() method function. Then the code forces the 0th field to an integer and checks for an exact match.

  • This code checks the input lines, and if they don't work, silently skips the line. Is that what you want? Maybe not! Maybe it would be better for the code to blow up if the database file is malformed. Then instead of using the continue statement, maybe you would want to put in a raise statement, and raise an exception. Maybe define your own MalformedDatabase exception, which should be a subclass of ValueError I think.

  • This code uses a pretty unique feature of Python, the else statement on a for loop. This is for code that is only executed when the loop runs all the way to the end, without an early exit. When the loop finds the customer ID, it exits early with a break statement; when the customer ID is never found, the loop runs to the end and this code executes.

  • This code will actually work okay with Python 2.x, but the error checking isn't quite adequate. If you run it under Python 3.x it is pretty well-checked. I'm assuming you are using Python 3.x to run this. If you run this with Python 2.x, enter xxx or crazy junk like 0zz and you will get different exceptions than just the ValueError being tested! (If you actually wanted to use this with Python 2.x, you should change input() to raw_input(), or catch more exceptions in the try/except.)

Upvotes: 1

Burhan Khalid
Burhan Khalid

Reputation: 174624

Another approach. Since the file is tab delimited, you can use the csv module as well.

This approach, unlike @gnibbler's answer, will read the entire file and then search its contents (so it will load the file in memory).

import csv

with open('customer.txt') as file:
   reader = csv.reader(file, delimiter='\t')
   lines = list(reader)

search = input('Please enter the id: ')
result = [line for line in lines if search in line]
print '\t'.join(*result) if result else 'Not Found'

Upvotes: 0

John La Rooy
John La Rooy

Reputation: 304137

Not sure, are the lines supposed to be split into fields somehow?

search = input("Please enter a CID to search for: ")
with open('customer.txt', 'r') as file:
    for line in file:
        fields = line.split('\t')
        if fields[0] == search:
            print(search, "was found in the database.")
            CID = fields[0]
            print(line)
            break
    else:
        print(search, "does not exist in the database.")

Upvotes: 2

Related Questions