How to create different files for each time a function is performed on an item in a for loop?

空扰寡人 提交于 2019-12-25 08:48:42

问题


So building off of a code below that a community member here helped me fine-tune to create a function that takes a dictionary value from a text file and looks then looks through that value for a list of files. This was the code where I was appending all the values found to the same sheet.

import csv
import glob
import ast
from os.path import isfile
from lxml import etree

def look_for_speaker_in_files(speakerAttrib):
    speakerDict = ast.literal_eval(speakerAttrib)
    l_file_exists = False
    if isfile("allspeakers.csv"):
        l_file_exists = True
    c = csv.writer(open("allspeakers.csv","a"))
    if not l_file_exists:
        c.writerow(["Name", "Filename", "Text"])
    lparser = etree.XMLParser(recover=True)
    for cr_file in glob.iglob('parsed/*.xml'):
        try:
          tree = etree.parse(cr_file,parser=lparser)
          for node in tree.iter('speaking'):
             if node.keys() == speakerDict.keys():
                c.writerow([node.attrib, cr_file, node.text])
             else:
                 continue
        except:
          print "bad string " + cr_file
          raise

def main():
    with open("speaking-basic.txt","r") as speaker_list:
        for x in speaker_list:
            print x
            look_for_speaker_in_files(x)
if __name__ == "__main__":
    main()

Now I am looking to create a different file for each item from the text file, and only deposit the matches for the nodes in the files, to that item from the text file.

I tried the code below, where I altered the function that reads through the files to try to get it to take both the argument for the file name and the argument for the item from the text file to be searched for. I then altered the code that takes the item from the list to both read the item from the list, and get it to create a file name that's the value of the dictionary items in the file.

import csv
import glob
import ast
from os.path import isfile
from lxml import etree

def look_for_speaker_in_files(speakerAttrib,file_name):
    speakerDict = ast.literal_eval(speakerAttrib)
    l_file_exists = False
    if isfile( file_name + ".csv"):
        l_file_exists = True
    c = csv.writer(open( file_name + ".csv","a"))
    print c
    if not l_file_exists:
        c.writerow(["Name", "Filename", "Text"])
    lparser = etree.XMLParser(recover=True)
    for cr_file in glob.iglob('parsed/*.xml'):
        try:
          tree = etree.parse(cr_file,parser=lparser)
          for node in tree.iter('speaking'):
             if node.keys() == speakerDict.keys():
                c.writerow([node.attrib, cr_file, node.text])
             else:
                 continue
        except:
          print "bad string " + cr_file
          raise

def main():
    with open("speaking.txt","r") as speaker_list:
        for x in speaker_list:
            print x
            dictx = ast.literal_eval(x)
            valuex = str(dictx.values()).format()
            print valuex
            look_for_speaker_in_files(x,valuex)
if __name__ == "__main__":
    main()

I also tried to keep the looking through the files function to the same single argument, but adding a variable that came up with the file name from that argument, but that also didn't work.

import csv
import glob
import ast
from os.path import isfile
from lxml import etree

def look_for_speaker_in_files(speakerAttrib):
    speakerDict = ast.literal_eval(speakerAttrib)
    file_name = str(speakerDict.values()).format()
    l_file_exists = False
    if isfile(file_name + ".csv"):
        l_file_exists = True
    c = csv.writer(open(file_name + ".csv","a"))
    if not l_file_exists:
        c.writerow(["Name", "Filename", "Text"])
    lparser = etree.XMLParser(recover=True)
    for cr_file in glob.iglob('parsed/*.xml'):
        try:
          tree = etree.parse(cr_file,parser=lparser)
          for node in tree.iter('speaking'):
             if node.keys() == speakerDict.keys():
                c.writerow([node.attrib, cr_file, node.text])
             else:
                 continue
        except:
          print "bad string " + cr_file
          raise

def main():
    with open("speaking-basic.txt","r") as speaker_list:
        for x in speaker_list:
            print x
            look_for_speaker_in_files(x)
if __name__ == "__main__":
    main()

While these codes create the files, with all my futzing with it I seem to only be able to get it to either put nothing in the files but the column headers, or put all the speakers from the xml files within each one, not just the one I've put into the function. Additionally I can't get it to create the file name without the [''] around it.

I have the xml files the function is searching through and the text file with the values I am looking for at the google link here: https://drive.google.com/open?id=0B7lGA34vOZItREhRbmF6Z3YtTnM

Any help on this would be super appreciated, thank you!


回答1:


I am not sure, if I understood your requirement correctly. Now what this code does is, with respect to the attribute given in the speaking-basic.txt, find the attributes in the parsed xml's. If the attribute name and its values match in both speaking-basic.txt and the xml's, then output it to a file with the name of the Speaker.

Check if this is what you were looking for, maybe I might not have understood it correctly. If so, please provide a clear understanding of the expected output with screenshots or samples.

import csv
import glob
import ast
from os.path import isfile
from lxml import etree

def look_for_speaker_in_files(speakerAttrib):
    speakerDict = ast.literal_eval(speakerAttrib)
    file_name = str(speakerDict.values()[0]).format()
    l_file_exists = False
    if isfile(file_name + ".csv"):
        l_file_exists = True
    c = csv.writer(open(file_name + ".csv","a"))
    if not l_file_exists:
        c.writerow(["Name", "Filename", "Text"])
    lparser = etree.XMLParser(recover=True)
    for cr_file in glob.iglob('parsed/*.xml'):
        try:
          tree = etree.parse(cr_file,parser=lparser)
          for node in tree.iter('speaking'):
             if node.keys() == speakerDict.keys():
                if node.values() == speakerDict.values():
                    c.writerow([node.attrib, cr_file, node.text])
                else:
                    continue
             else:
                 continue
        except:
          print "bad string " + cr_file
          raise

def main():
    with open("speaking-basic.txt","r") as speaker_list:
        for x in speaker_list:
            print x
            look_for_speaker_in_files(x)
if __name__ == "__main__":
    main()


来源:https://stackoverflow.com/questions/36962273/how-to-create-different-files-for-each-time-a-function-is-performed-on-an-item-i

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!