I'm using the following code to search for a list of IDs in a particular column of a csv file
#!/usr/bin/python
import csv
import sys
with open(r"C:\Test\inputTest.csv", newline = '') as inputFile:
inputReader = csv.reader(inputFile, delimiter=",")
idFile = open(r"C:\Test\testids.txt")
loopcounter = 1
for inputRow in inputReader:
loopcountr = 1
print (loopcounter)
inputString = inputRow[18]
for id in idFile:
print ("id: ", id)
print ("InputString", inputString)
result = inputString.find(id)
print (result)
But the nested loop with the id file runs only once, and then doesn't run again.
Output:
1
id: 123388
InputString ID
-1
id: 112233
InputString ID
-1
id: 141414
InputString ID
-1
2
3
4
5
6
7
8
9
10
Any idea why the 2nd loop (the nested loop) doesn't run every time?
CodePudding user response:
Like Tim Roberts mentioned in the comment, "You should read idFile into a list, and then iterate over the list."
You can read the test IDs into a list, like this:
with open("test_ids.txt") as f:
test_ids = []
for line in f:
test_ids.append(line.strip())
Or, if you're comfortable with list comprehensions in Python, this is equivalent:
with open("test_ids.txt") as f:
test_ids = [x.strip() for x in f.readlines()]
Then, when you're reading the CSV file (presumably) you can compare some data from the CSV against the test IDs.
That could look something like the following. I'm also using enumerate()
to count the iterations for me:
with open("input.csv", newline="") as f:
reader = csv.reader(f)
next(reader) # discard header
for i, row in enumerate(reader, 1):
input_id = row[0] # don't use 'id', it's a reserved word
name = row[1]
print(f"row #:{i}, input_ID:{input_id}, Name:{name}")
for test_id in test_ids:
if test_id == input_id:
print(f" {name} matches test_ID {test_id}")
I mocked up this data. The CSV has the ID in the first column, row[0]
from the code above:
test_ids.txt
============
105
108
input.csv
=========
ID,Name
105,Alice
106,Bing
107,Che
108,Dee
When I run that code I get:
row #:1, input_ID:105, Name:Alice
Alice matches test_ID 105
row #:2, input_ID:106, Name:Bing
row #:3, input_ID:107, Name:Che
row #:4, input_ID:108, Name:Dee
Dee matches test_ID 108
And that's how you can implement a nested loop.
If you're comfortable with doing "lookups" in dictionaries, you can get rid of the nested loop:
with open("test_ids.txt") as f:
test_ids = {}
for line in f:
test_ids[line.strip()] = None
The test_ids dictionary looks like:
{'105': None, '108': None}
And now you simply check if each input ID is "in" that dictionary:
with open("input.csv", newline="") as f:
...
for i, row in enumerate(reader, 1):
...
if input_id in test_ids:
print(f" {name} found in test_IDs")
That produces the similar output:
row #:1, input_ID:105, Name:Alice
Alice found in test_IDs
row #:2, input_ID:106, Name:Bing
row #:3, input_ID:107, Name:Che
row #:4, input_ID:108, Name:Dee
Dee found in test_IDs