String 通过硬编码键检索dict值,有效。通过计算键进行检索不需要';T为什么?

String 通过硬编码键检索dict值,有效。通过计算键进行检索不需要';T为什么?,string,python-2.7,list,dictionary,format,String,Python 2.7,List,Dictionary,Format,我通过比较两组ID(ID集来自字典,{ID:XML“RECORD”element})来生成一个常见的ID列表。一旦我有了公共列表,我想迭代它并从字典中检索对应于ID的值(我将把它写入光盘) 当我使用diff_comm_checker函数计算公共ID列表时,我无法检索ID对应的dict值。然而,它不会因为键错误而失败。我也可以把身份证打印出来 当我将ID硬编码为公共_ID值时,我可以检索dict值 即 我得到的两个结果完全相同: >>> ('0603599998140032MB'

我通过比较两组ID(ID集来自字典,
{ID:XML“RECORD”element}
)来生成一个常见的ID列表。一旦我有了公共列表,我想迭代它并从字典中检索对应于ID的值(我将把它写入光盘)

当我使用diff_comm_checker函数计算公共ID列表时,我无法检索ID对应的dict值。然而,它不会因为键错误而失败。我也可以把身份证打印出来

当我将ID硬编码为公共_ID值时,我可以检索dict值

我得到的两个结果完全相同:

>>> ('0603599998140032MB', <type 'str'>, "'0603599998140032MB'")
所以,这两者似乎没有任何区别

下面是一个完整的工作代码示例:

from StringIO import StringIO
import xml.etree.cElementTree as ET
from itertools import chain, islice

def diff_comm_checker(list_1, list_2, text):
    """Checks 2 lists. If no difference, pass. Else return common set between two lists"""

    symm_diff = set(list_1).symmetric_difference(list_2)
    if not symm_diff:
        pass
    else:
        mismatches_in1_not2 = set(list_1).difference( set(list_2) )
        mismatches_in2_not1 = set(list_2).difference( set(list_1) )

        if mismatches_in1_not2:
            mismatch_logger(
                mismatches_in1_not2,"{}\n1: {}\n2: {}".format(text, list_1, list_2), 1, 2)
        if mismatches_in2_not1:
            mismatch_logger(
                mismatches_in2_not1,"{}\n2: {}\n1: {}".format(text, list_1, list_2), 2, 1)

    set_common = set(list_1).intersection( set(list_2) )
    if set_common:
        return sorted(set_common)
    else:
        return "no common set: {}\n".format(text)


def chunks(iterable, size=10):
    iterator = iter(iterable)
    for first in iterator:
        yield chain([first], islice(iterator, size - 1))

def get_elements_iteratively(file):
    """Create unique ID out of image number and case number, return it along with corresponding xml element"""

    tag = "RECORD"

    tree = ET.iterparse(StringIO(file), events=("start","end"))
    context = iter(tree)
    _, root = next(context)

    for event, record in context:
        if event == 'end' and record.tag == tag:
            xml_element_2 = ''
            xml_element_1 = ''
            for child in record.getchildren():
                if child.tag == "IMAGE_NUMBER":
                    xml_element_1 = child.text
                if child.tag == "CASE_NUM":
                    xml_element_2 = child.text
            r_id = "{}{}".format(xml_element_1, xml_element_2)
            record.set("R", r_id)
            yield (r_id, record)
            root.clear()

def get_chunks(file, chunk_size):
    """Breaks XML into chunks, yields dict containing unique IDs and corresponding xml elements"""

    iterable = get_elements_iteratively(file)

    for chunk in chunks(iterable, chunk_size):
        ids_records = {}
        for k in chunk:
            ids_records[k[0]]=k[1]

        yield ids_records

def create_new_xml(xml_list):

    chunk = 5000

    chunk_rec_ids_1 = get_chunks(xml_list[0], chunk)
    chunk_rec_ids_2 = get_chunks(xml_list[1], chunk)
    to_write = [chunk_rec_ids_1, chunk_rec_ids_2]

    ######################################################################################
    ### WHAT'S GOING HERE ??? WHAT'S THE DIFFERENCE BETWEEN THE OUTPUTS OF THESE TWO ? ###

    common_ids = diff_comm_checker( [x.keys() for x in to_write[0]][0], [x.keys() for x in to_write[1]][0], "create_new_xml - large - common_ids")
    #common_ids = ['0603599998140032MB']

    ######################################################################################

    for _id in common_ids:
        print _id
        for gen_obj in to_write:
            for kv_pair in gen_obj:
                if kv_pair[_id]:
                    print _id, kv_pair[_id].attrib, kv_pair[_id]


if __name__ == '__main__':

    xml_1 = """<?xml version="1.0"?><RECORDSET><RECORD><CASE_NUM>140032MB</CASE_NUM><IMAGE_NUMBER>0603599998</IMAGE_NUMBER></RECORD></RECORDSET>"""
    xml_2 = """<?xml version="1.0"?><RECORDSET><RECORD><CASE_NUM>140032MB</CASE_NUM><IMAGE_NUMBER>0603599998</IMAGE_NUMBER></RECORD></RECORDSET>"""
    create_new_xml([xml_1, xml_2])
从StringIO导入StringIO
将xml.etree.cElementTree作为ET导入
来自itertools进口链,islice
def差异通信检查器(列表1、列表2、文本):
“”“检查两个列表。如果没有差异,则通过。否则返回两个列表之间的公共集”“”
对称差异=集合(列表1)。对称差异(列表2)
如果不是对称的:
通过
其他:
不匹配(在1中)不匹配2=集合(列表1)。差异(集合(列表2))
不匹配2\u not1=集合(列表2)。差异(集合(列表1))
如果1中的不匹配2:
不匹配记录器(
不匹配_in1_not2,“{}\n1:{}\n2:{}”。格式(文本,列表_1,列表_2),1,2)
如果2\u not1中的\u不匹配:
不匹配记录器(
不匹配2_not1,“{}\n2:{}\n1:{}”。格式(文本,列表_1,列表_2),2,1)
集合公共=集合(列表1)。交叉点(集合(列表2))
如果设置为公共:
返回已排序(设置为公共)
其他:
返回“无公共集:{}\n”。格式(文本)
def块(iterable,size=10):
迭代器=iter(iterable)
对于first-in迭代器:
收益链([第一],islice(迭代器,大小-1))
def以迭代方式获取元素(文件):
“”“使用图像编号和案例编号创建唯一ID,并将其与相应的xml元素一起返回”“”
tag=“记录”
tree=ET.iterparse(StringIO(文件),events=(“开始”,“结束”))
上下文=iter(树)
_,root=next(上下文)
对于事件,在上下文中记录:
如果event='end'和record.tag==tag:
xml_元素_2=''
xml_元素_1=''
对于记录中的子项。getchildren():
如果child.tag==“图像编号”:
xml_元素_1=child.text
如果child.tag==“CASE_NUM”:
xml_元素_2=child.text
r_id=“{}{}”。格式(xml_元素_1,xml_元素_2)
记录集(“R”,R\u id)
收益率(r_id,记录)
root.clear()
def get_块(文件、块大小):
“”“将XML分解为块,生成包含唯一ID和相应XML元素的dict”“”
iterable=以迭代方式获取元素(文件)
对于块中块(iterable,chunk\u size):
ids_记录={}
对于块中的k:
ids_记录[k[0]]=k[1]
产量记录
def创建新的xml(xml列表):
区块=5000
chunk\u rec\u ids\u 1=获取\u块(xml\u列表[0],块)
chunk\u rec\u ids\u 2=获取\u块(xml\u列表[1],块)
to_write=[chunk_rec_ids_1,chunk_rec_ids_2]
######################################################################################
###这是怎么回事???这两者的输出有什么不同###
公共_id=diff_comm_checker([x.keys()用于x-in-to-_-write[0]][0],[x.keys()用于x-in-to-_-write[1]][0],“创建新的_-xml-大型-公共_id”)
#公共_id=['0603599998140032MB']
######################################################################################
对于公共\u id中的\u id:
打印id
对于gen_obj in to_write:
对于gen_obj中的kv_对:
如果kv_对[_id]:
打印_-id,千伏对[_-id]。属性,千伏对[_-id]
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
xml_1=“”140032MB0603599998”“”
xml_2=“”140032MB0603599998”“”
创建新的xml([xml\U 1,xml\U 2])

问题不在于diff\u comm\u checker返回的公共ID的类型或值。问题在于函数diff_comm_checker或在构造函数的参数时破坏了to_write的值

如果你试试这个,你就会明白我的意思

common_ids = ['0603599998140032MB']
diff_comm_checker( [x.keys() for x in to_write[0]][0], [x.keys() for x in to_write[1]][0], "create_new_xml - large - common_ids")
这将给出错误的行为,而不使用diff_comm_checker()的返回值

这是因为to_write是一个生成器,对diff_comm_checker的调用会耗尽该生成器。然后,当在循环中的if语句中使用生成器时,它将完成/清空。您可以使用列表从生成器创建列表:

但这可能有其他影响(内存使用…)

另外,在diff_comm_checker中这个构造的意图是什么

    if not symm_diff:
       pass

在我看来,无论symm_diff是否为None,都不会发生任何事情。

我排除了一些代码,因为我认为这些代码不相关,现在我已经将它们放回原处。如果两个集合之间没有差异,我想跳过
difference()
函数。那么有什么方法可以使用
diff\u comm\u checker
func而不破坏
的值来写入
?我将尝试在
ids\u records
dict旁边返回一个列表,但是如果有更好的方法,请告诉我写入是一个生成器,而不是列表。您对diff_com_checker的调用将耗尽生成器中的项目。当你以后尝试再次使用发电机时,它是空的,我现在理解了这个问题。我已经尝试按照您的建议生成一个列表,但在构建列表的过程中确实存在内存问题。我将寻找另一种方法来做到这一点。我会在2小时内拿到赏金。
from StringIO import StringIO
import xml.etree.cElementTree as ET
from itertools import chain, islice

def diff_comm_checker(list_1, list_2, text):
    """Checks 2 lists. If no difference, pass. Else return common set between two lists"""

    symm_diff = set(list_1).symmetric_difference(list_2)
    if not symm_diff:
        pass
    else:
        mismatches_in1_not2 = set(list_1).difference( set(list_2) )
        mismatches_in2_not1 = set(list_2).difference( set(list_1) )

        if mismatches_in1_not2:
            mismatch_logger(
                mismatches_in1_not2,"{}\n1: {}\n2: {}".format(text, list_1, list_2), 1, 2)
        if mismatches_in2_not1:
            mismatch_logger(
                mismatches_in2_not1,"{}\n2: {}\n1: {}".format(text, list_1, list_2), 2, 1)

    set_common = set(list_1).intersection( set(list_2) )
    if set_common:
        return sorted(set_common)
    else:
        return "no common set: {}\n".format(text)


def chunks(iterable, size=10):
    iterator = iter(iterable)
    for first in iterator:
        yield chain([first], islice(iterator, size - 1))

def get_elements_iteratively(file):
    """Create unique ID out of image number and case number, return it along with corresponding xml element"""

    tag = "RECORD"

    tree = ET.iterparse(StringIO(file), events=("start","end"))
    context = iter(tree)
    _, root = next(context)

    for event, record in context:
        if event == 'end' and record.tag == tag:
            xml_element_2 = ''
            xml_element_1 = ''
            for child in record.getchildren():
                if child.tag == "IMAGE_NUMBER":
                    xml_element_1 = child.text
                if child.tag == "CASE_NUM":
                    xml_element_2 = child.text
            r_id = "{}{}".format(xml_element_1, xml_element_2)
            record.set("R", r_id)
            yield (r_id, record)
            root.clear()

def get_chunks(file, chunk_size):
    """Breaks XML into chunks, yields dict containing unique IDs and corresponding xml elements"""

    iterable = get_elements_iteratively(file)

    for chunk in chunks(iterable, chunk_size):
        ids_records = {}
        for k in chunk:
            ids_records[k[0]]=k[1]

        yield ids_records

def create_new_xml(xml_list):

    chunk = 5000

    chunk_rec_ids_1 = get_chunks(xml_list[0], chunk)
    chunk_rec_ids_2 = get_chunks(xml_list[1], chunk)
    to_write = [chunk_rec_ids_1, chunk_rec_ids_2]

    ######################################################################################
    ### WHAT'S GOING HERE ??? WHAT'S THE DIFFERENCE BETWEEN THE OUTPUTS OF THESE TWO ? ###

    common_ids = diff_comm_checker( [x.keys() for x in to_write[0]][0], [x.keys() for x in to_write[1]][0], "create_new_xml - large - common_ids")
    #common_ids = ['0603599998140032MB']

    ######################################################################################

    for _id in common_ids:
        print _id
        for gen_obj in to_write:
            for kv_pair in gen_obj:
                if kv_pair[_id]:
                    print _id, kv_pair[_id].attrib, kv_pair[_id]


if __name__ == '__main__':

    xml_1 = """<?xml version="1.0"?><RECORDSET><RECORD><CASE_NUM>140032MB</CASE_NUM><IMAGE_NUMBER>0603599998</IMAGE_NUMBER></RECORD></RECORDSET>"""
    xml_2 = """<?xml version="1.0"?><RECORDSET><RECORD><CASE_NUM>140032MB</CASE_NUM><IMAGE_NUMBER>0603599998</IMAGE_NUMBER></RECORD></RECORDSET>"""
    create_new_xml([xml_1, xml_2])
common_ids = ['0603599998140032MB']
diff_comm_checker( [x.keys() for x in to_write[0]][0], [x.keys() for x in to_write[1]][0], "create_new_xml - large - common_ids")
chunk_rec_ids_1 = list(get_chunks(xml_list[0], chunk))
chunk_rec_ids_2 = list(get_chunks(xml_list[1], chunk))
    if not symm_diff:
       pass