Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 循环函数直到失败的最佳方法?_Python_Python 2.7_Function_Loops - Fatal编程技术网

Python 循环函数直到失败的最佳方法?

Python 循环函数直到失败的最佳方法?,python,python-2.7,function,loops,Python,Python 2.7,Function,Loops,免责声明: 我可能问的是“错误的方式”——我还是个新手 对于编程,我可能缺少正确的术语和 理解正确地提出问题。对不起,如果我 是的 我知道你不能用正则表达式解析[X]HTML。我不是在分析 信息技术我只是在匹配一个字符串以获得该字符串行的计数 我试过lxml和iter(),以及iterparse(),我试过了。这对我不起作用。我是这样做的 我知道这里的代码效率不高(特别是每次调用函数时编译regex表达式)——我这样重新编写代码是为了提供询问问题所需的“最少代码”,另外,我认为这使我更容易理解我

免责声明:

  • 我可能问的是“错误的方式”——我还是个新手 对于编程,我可能缺少正确的术语和 理解正确地提出问题。对不起,如果我 是的
  • 我知道你不能用正则表达式解析[X]HTML。我不是在分析 信息技术我只是在匹配一个字符串以获得该字符串行的计数
  • 我试过
    lxml
    iter()
    ,以及
    iterparse()
    ,我试过了。这对我不起作用。我是这样做的
  • 我知道这里的代码效率不高(特别是每次调用函数时编译regex表达式)——我这样重新编写代码是为了提供询问问题所需的“最少代码”,另外,我认为这使我更容易理解我试图实现的目标
  • 一路走来;这段代码工作正常,并且实现了我希望它做的事情,基本上就是获取大量xml记录,并将其转换为
    {record\u id:{element\u tag:element\u val,element\u tag:element\u val,…}
    形式的字典

    由于记录id嵌套在记录本身中,我首先使用
    记录拆分器
    来标识
    (beg
    end
    )的计数。我将
    beg
    end
    传递到
    dic_工厂
    ,该工厂找到这些位置,对其中嵌套的元素进行处理,然后将“beg”设置为
    end+1
    ,并将其传递回
    记录分割器
    功能

    我的问题是,是否有更好的方法来实现函数之间的循环,最好是在
    下,如果
    ,那么我可以移动更多的常量(例如regex语句)

    Code:
        # stored as a text file, but here for clarity
    
        list_of_lines = """
        <RECORD>
          <TITLE>MISS</TITLE>
          <NAME>ELIZABETH</NAME>
          <SURNAME>II</SURNAME>
          <ADDRESS1>1 BUCKINGHAM PALACE</ADDRESS1>
          <ADDRESS2>LONDON</ADDRESS2>
          <ADDRESS3>GREATER LONDON</ADDRESS3>
          <POST_CODE>W1 11A</POST_CODE>
          <CASE_NUM>Q1QQ1234</CASE_NUM>
          <ID>32145698</ID>
          <LAST_UPDATE_DATE>2016-12-12</LAST_UPDATE_DATE>
         </RECORD>
         <RECORD>
          <TITLE>MR</TITLE>
          <NAME>PRINCE</NAME>
          <SURNAME>PHILLIP</SURNAME>
          <ADDRESS1>1 BUCKINGHAM PALACE</ADDRESS1>
          <ADDRESS2>LONDON</ADDRESS2>
          <ADDRESS3>GREATER LONDON</ADDRESS3>
          <POST_CODE>W1 11A</POST_CODE>
          <CASE_NUM>K5KK4321</CASE_NUM>
          <ID>56987412</ID>
          <LAST_UPDATE_DATE>2017-01-16</LAST_UPDATE_DATE>
         </RECORD>
         <RECORD>
        """
    
    class recordManager:
    
        def __init__(self):
            self.r_location = "list_of_lines.txt"
    
        def record_splitter(self, beg):
    
            re_beg_spl = re.compile(".*<RECORD>")
            re_end_spl = re.compile(".*(<\\/RECORD>)")
    
            end = None
    
            for count, line in enumerate( open(self.r_location) ):
                if count > beg:
                    if re_end_spl.match(line):
                        end = count
    
                        if not re_end_spl.match(line):
                            if re_beg_spl.match(line):
                                beg = count
                        else:
                            break
    
                        recordManager.dic_factory(self, beg, end)
    
    
        def dic_factory(self, beg, end):
    
            re_casenum = re.compile(".*<CASE_NUM>(.*)<\\/CASE_NUM>")
            re_tag_val = re.compile(".*<(\\w*)>(.*)<.*")
    
            id_ = None
            tags = []
            vals = []
    
            for count, line in enumerate( open(self.r_location) ):
    
                if beg < count < end:
                    if re_casenum.match(line):
                        m = re_casenum.match(line)
                        id_ = m.group(1)
    
                    if re_tag_val.match(line):
                        m = re_tag_val.match(line)
                        tags.append( m.group(1) )
                        vals.append( m.group(2) )
    
            beg = end +1
            print {id_ : dict(zip(tags, vals)) }
            # {32145698 : {'POST_CODE': 'W1 11A', 'SURNAME': 'II', 'NAME': 'ELIZABETH', 'TITLE': 'MISS', 'ADDRESS1': '1 BUCKINGHAM PALACE', 'ADDRESS2': 'LONDON', 'ADDRESS3': 'GREATER LONDON', 'RECORD_TYPE': '1', 'CASE_NUM': 'Q1QQ1234', 'LAST_UPDATE_DATE': '2016-12-12', 'ID': '32145698'}}
    
            self.record_splitter(beg)
    
    
    if __name__ == '__main__':
        inst_fol = record_manager(file)
        recordManager.record_splitter(inst_folder, 0)
    

    这是“从函数内部循环”吗?如果不是,更好的方法是什么;dr:用self.beg替换beg

    我的建议是将
    beg
    列为你班上的一个字段。请记住,您使用的每个方法都可以访问
    self
    ,这是将此工作组织到一个类中的一部分优势:

    所以
    \uuuu init\uuuu
    变成:

        def __init__(self):
        self.r_location = "list_of_lines.txt"
        self.beg = 0
    
    现在,无论你在哪里使用
    beg
    你都把它称为
    self.beg

    例如:

            for count, line in enumerate( open(self.r_location) ):
            if count > self.beg:
                if re_end_spl.match(line):
                    end = count
    
                    if not re_end_spl.match(line):
                        if re_beg_spl.match(line):
                            self.beg = count
                    else:
                        break
    
                    recordManager.dic_factory(self, self.beg, end)
    
    请注意,还有进一步的整合机会:
    dic_factory
    beg
    作为参数,但它也可以访问对象
    self
    ,并且可以简单地从该字段读取
    beg

    我建议您在同一迭代器上使用嵌套循环,而不是单独的函数。(详情见评论)

    类记录管理器:
    定义初始化(自):
    self.r\u location=“list\u of\u lines.txt”
    self.records=[]#也许我们要存储找到的所有记录?
    def find_记录(自我):
    re_beg_spl=re.compile(“.*”)
    re\u end\u spl=re.compile(“”()“”)
    re_casenum=re.compile(“.*(.*)”)#将它们移到这里,因为我们正在将两个函数合并为一个函数
    
    re_tag_val=re.compile(.*(*)澄清:您是否在询问如何在
    \uu main\uuuu
    中首次调用后将变量
    beg
    返回到函数
    记录\u拆分器中?这是正确的-我希望它这样做,直到失败为止(即,直到它处理了
    列表中的所有行。txt
    )如果您的最终目标是将xml放入dict,您可以检查:,,不要像字符串一样解析xml!学习如何使用lxml或xml.etree解析它,然后构建dict。@Ywapom看起来很有趣,我会尝试一下。只要它不尝试将整个文件加载到内存中,它可能会工作。谢谢。@Igle-我已经尝试过lxml(参见免责声明的第3点)。它将整个文件加载到内存中。对我不起作用。使用
    clear()尝试
    iterparse()
    。对我来说也不起作用。让我试试这个,然后再回来找你。我确信我之前也尝试过类似的方法,但在更改Damn的值时出现了一个问题,这是一个快速、优雅的解决方案,我学到了一些新的东西(嵌套循环)。非常感谢。请你解释一下这一行-
    标记[match\u elem.group](1) ]=match_elem.group(2)
    ?@rong是python字典的快速入门。
    tags
    每次启动新记录时都作为空字典启动:
    tags={}
    。然后,我使用
    标记值的第一组作为键,第二组作为新字典条目的值。基本上,我是以增量方式向输出字典添加值,而不是单独收集键和值,然后在末尾使用
    dict(zip(标记,val))创建dict
    正如您在第一个示例中所做的。
            for count, line in enumerate( open(self.r_location) ):
            if count > self.beg:
                if re_end_spl.match(line):
                    end = count
    
                    if not re_end_spl.match(line):
                        if re_beg_spl.match(line):
                            self.beg = count
                    else:
                        break
    
                    recordManager.dic_factory(self, self.beg, end)
    
    class recordManager:
    
        def __init__(self):
            self.r_location = "list_of_lines.txt"
            self.records = [] #perhaps we want to store all the records we find?
    
        def find_records(self):
    
            re_beg_spl = re.compile(".*<RECORD>")
            re_end_spl = re.compile(".*(<\\/RECORD>)")
            re_casenum = re.compile(".*<CASE_NUM>(.*)<\\/CASE_NUM>") #move these up here since we're rolling the two functions into one
            re_tag_val = re.compile(".*<(\\w*)>(.*)<.*")
    
            with open(self.r_location) as f: #use the "with open() as f:" idiom to ensure file gets closed when you're done with it
                for line in f: #iterating over an open file defaults to line by line and we won't need line number with the nested loop approach
                    if re_beg_spl.match(line): #start a new record
                        tags = {} #container for element tags and values
                        case = '' #case number for this record
                        for line in f: #re-use iterator for inner loop so lines are consumed (outer loop will pick up where inner loop leaves off)
                            match_case = re_casenum.match(line)
                            match_elem = re_tag_val.match(line)
                            match_end = re_end_spl.match(line)
                            if match_case:
                                case = match_case.group(1) #are match groups 1 or 0 indexed? I didn't look it up..
                            elif match_elem:
                                tags[match_elem.group(1)] = match_elem.group(2)
                            elif match_end: #end of a record -- save info and break out of inner loop
                                caseinfo = {case: tags}
                                print(caseinfo)
                                self.records.append(caseinfo)
                                break