Alex
Alex

Reputation: 3

return a list of word from a texte file with python

I work on a project on python. I want to return a list of name from a text file. I start with one name I know. My text file is like :

ALPHA;n10;Output 
ALPHA;n11;Input 
ALPHA;n12;Input 
BETA;n10;Input 
BETA;n14;Input 
CHARLIE;n10;Input 
CHARLIE;n13;Output 
DELTA;n13;Output 
DELTA;n12;Input

Let's say I start from the name ALPHA and I know it's an Output. So I have to search the number link to this name which is n10. I want to return all the name of the number n10 which are in Input. So at the end I want the list ["BETA", "CHARLIE"]

For the moment I code the following function :

file = "path of the texte file"
name = "ALPHA"
liste_new_name = []
def search_new_name(liste):
    file_txt = open(file, "r")
    contenu = file_txt.readline()
    file_txt.close()
    if contenu.split(";")[0] == name and ";Output" in contenu:
        num = contenu.split(";")[1]
        if num in contenu and ";Input" in contenu:
             liste.append(contenu.split(";")[0]
             return liste
             print(liste)
        else:
             print("No new name found")
    else:
        print("No num found")

search_new_name(liste_new_name)

My problem is that I have "No num found" but like the example I know I should have a list.

Upvotes: 0

Views: 330

Answers (3)

001
001

Reputation: 13533

I would parse the file into a dictionary. This will make searching much easier and will allow you to do multiple searches without having to re-read the file:

def parse_file(path):
    data = {}
    with open(path, 'r') as in_file:
        for line in in_file:
            try:
                name, n, direction = line.strip().split(';')
                if name not in data:
                    data[name] = {"Input": [], "Output": []}
                data[name][direction].append(n)
            except KeyError:
                print(f"Error with: {line}")
            except ValueError:
                pass
    return data

This will return a dictionary like:

{
'ALPHA': {'Input': ['n11', 'n12'], 'Output': ['n10']},
'BETA': {'Input': ['n10', 'n14'], 'Output': []},
'CHARLIE': {'Input': ['n10'], 'Output': ['n13']},
'DELTA': {'Input': ['n12'], 'Output': ['n13']}
}

With that searches can be done with a simple list comprehension:

def search_new_name(name, data):
    if name not in data: return None
    return [key for key,value in data.items() if any(x in data[key]["Input"] for x in data[name]["Output"])]

Sample usage:

data = parse_file(r"C:\foo\bar.txt")
print(search_new_name("ALPHA", data))

Output:

['BETA', 'CHARLIE']

Upvotes: 1

Alex
Alex

Reputation: 3

I try to continue with my idea with two functions like that :

file = "path of the text file"
name = "ALPHA"
new_l_name = []
num = []

def search_num(num):
    file_txt = open(file, "r")
    contenu = file_txt.readline()
    while contenu:
        contenu = fichier_txt.readline()
        if contenu.split(";")[0] == name and ";Output" in contenu:
            num.append(contenu.split(";")[1]
            return num
    else:
        print("No num found")
    file_txt.close()

search_num(num)

def search_new_name(liste):
    file_txt = open(file, "r")
    contenu = file_txt.readline()
    while contenu:
        contenu = file_txt.readline()
        if contenu.split(";")[1] == num[0] and ";Input" in contenu:
            new_name = contenu.split(";")[0]
            liste.append(new_name)
            print("the list of new name : {}".format(liste))
            return liste
    else:
        print("No new name found")

search_new_name(new_l_name)
    

Finally, I have the num we search in return but the list of the new name return the list with the first new name found in the textfile but not the others. It returns ["BETA"] and not ["BETA", "CHARLIE"] as we want.

If someone have an idea.

Thanks.

Upvotes: 0

Amulya
Amulya

Reputation: 58

You will have to read all the lines and creating a dictionary with the 'number' and 'type' combination as the key will solve the problem.

file = "path of the texte file"
name = "ALPHA"
liste_new_name = []

def search_new_name(name):
    name_map = {} ## dict to save all the info
    search_key = False
    file_txt = open(file, "r")
    all_lines = file_txt.readlines()
    for contenu in all_lines:
        [l_name,l_num,l_type] = contenu.split(";")
        key = l_num + "_" + l_type ## use num and type combination as a key
        if l_name == name and l_type == "Output":
            search_key = l_num+"_"+l_type
        if key in name_map:
            name_map[key] = name_map[key].append(l_name)
        else:
            name_map[key] = [l_name]

    if search_key is False:
        print("Num not found")
        return []
    else:
        search_num = search_key.split('_')[0]
        if search_num+'_Input' in name_map:
            return name_map[search_num+'_Input']
        else:
            ## return empty list if no input found
            return []


search_new_name(name)

Upvotes: 0

Related Questions