Search code examples
pythonpython-3.xnested-loops

Python, How to make a nested loop works with multiple columns csv files?


I am new to Python, I want to make a function work using data from multiple columns CSV files, one row by one row with some delay in between each run.

This is want I want to achieve:

  1. Read from first CSV file within a range ( e.g. row 0 to row 3)

  2. Use the data of one row, to put in the right parameter section inside function, some delay and do the same with next row.

  3. some delay, then it goes to next CSV file, until the last CSV file.

I have the tried the following code, but not working. The following code works fine with one column CSV file.

there are 4 parameter that I want to be filled with data from CSV file, using the same Column header name as parameter name inside the function.

sample csv file:

img_path,desc_1 title_1,link_1
site.com/image22.jpg,someTitle,description1,site1.com
site.com/image32.jpg,someTitle,description2,site2.com
site.com/image44.jpg,someTitle,description3,site3.com
from abc.zzz  import xyz
path_id_map = [
    {'path':'file1.csv', 'id': '12345678'},
    {'path':'file2.csv', 'id': '44556677'}
    {'path':'file3.csv', 'id': '33377799'}
    {'path':'file4.csv', 'id': '66221144'}]
s_id = None
for pair in path_id_map:
    with open(pair['path'], 'r') as f:
        for i in range(0, 3):      
            zzz.func1(img_path=f.readline().rstrip(','), title_1=f.readline().rstrip(','), 
            desc_1=f.readline().rstrip(','), link_1=f.readline().rstrip(','), B_id=pair['id'], 
            s_id=s_id)
            return zzz.func1(img_file=img_path, title_1=title_1, desc_1=desc_1, 
                 link_1=link_1, B_id=B_id, s_id=s_id)
            time.sleep(25) 

Appreciate your help to make it work.


Solution

    • Every time you call readline() you move over to the next line. So first save that line to a variable and then process it.
    • rstrip only removes characters from the edges of the string. As you have no trailing commas, the use of rstrip in your code has no effect. It seems like you meant to use the split method instead to take the different parts separated by commas.
    for pair in path_id_map:
        with open(pair['path'], 'r') as f:
            next(f)  # skip first header line
            for _ in range(0, 3):      
                line = next(f)
                img_path, desc_1, title_1, link_1 = map(str.strip, line.split(','))
                zzz.func1(img_path=img_path, title_1=title_1, desc_1=desc_1, 
                          link_1=link_1, B_id=pair['id'], s_id=s_id)
    

    But there is no need to parse csv files manually. Instead, you can use the built-in csv module, which has the DictReader that reads each line to a dict where the keys are the headers and the values are the value of each column with that header. This will allow you to simply unpack the row into the function call:

    import csv
    
    for pair in path_id_map:
        with open(pair['path'], 'r') as f:
            reader = csv.DictReader(f)
            for _ in range(0, 3):      
                line = next(reader)
                zzz.func1(B_id=pair['id'], s_id=s_id, **line)