调试行为与python中的正常执行不同

时间:2016-08-03 12:22:38

标签: python pandas

我试图弄清楚为什么我的代码行为与正常执行不同。我见过这个,但不是我的情况:

  

What to do, if debug behaviour differs from normal execution?

     

python2.7 using debug behave different then without debug

我正在将XML文档解析为DataFrame,因此我可以转换为csv或excel文件。正常执行时,它只解析“LOCALIDADE”节点的最后一个“CPE”。

这是我的xml文件的一大块:

<DISTRITO xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <NOME_DISTRITO>BRAGANCA</NOME_DISTRITO>

  <CONCELHO>
    <NOME_CONCELHO>ALFANDEGA DA FE</NOME_CONCELHO>
    <FREGUESIA>
      <NOME_FREGUESIA>AGROBOM</NOME_FREGUESIA>
      <LOCALIDADE>
        <NOME_LOCALIDADE>AGROBOM</NOME_LOCALIDADE>
        <CODIGO_POSTAL>5350</CODIGO_POSTAL>
        <CPE>PT2000022152377DE</CPE>
        <CPE>PT2000022152388XX</CPE>
        <CPE>PT2000022152399XK</CPE>
        <CPE>PT2000022152402BR</CPE>
        <CPE>PT2000022152424NT</CPE>
      </LOCALIDADE>
    </FREGUESIA>

    <FREGUESIA>
      <NOME_FREGUESIA>ALFANDEGA DA FE</NOME_FREGUESIA>
      <LOCALIDADE>
        <NOME_LOCALIDADE>ALFANDEGA DA FE</NOME_LOCALIDADE>
        <CODIGO_POSTAL>5350</CODIGO_POSTAL>
        <CPE>PT2000022153052QF</CPE>
        <CPE>PT2000022153085VV</CPE>
        <CPE>PT2000022153108HV</CPE>
        <CPE>PT2000022153119LM</CPE>
      </LOCALIDADE>
    </FREGUESIA>
  </CONCELHO>
</DISTRITO>

当我调试它时,此代码适用于我:

import xml.etree.ElementTree as et
import pandas as pd

path = '/Path/toFile.xml'
data = []
for (ev,el) in et.iterparse(path):
        print (el.tag, el.text)        
        if el.tag == 'NOME_DISTRITO': nome = el.text 
        if el.tag == 'NOME_CONCELHO': nc = el.text
        if el.tag == 'NOME_FREGUESIA': nf = el.text
        if el.tag == 'NOME_LOCALIDADE': nl = el.text
        if el.tag == "LOCALIDADE":
            inner = {}
            inner['NOME_DISTRITO'] = nome
            inner['NOME_CONCELHO'] = nc
            inner['NOME_FREGUESIA'] = nf            
            for i in el:                               
                print (i.tag,i.text)
                print(data)
                inner[i.tag] = i.text
                if inner.has_key('CPE'):
                    data.append(inner)   

df = pd.DataFrame(data)
df.to_csv('/Users/DanielMelo/Documents/Endesa/Portugal/CPE.csv',columns=['CPE','NOME_CONCELHO','NOME_FREGUESIA',
                                     'NOME_LOCALIDADE','CODIGO_POSTAL'])

但这是我正常执行时的结果:

CPE NOME_CONCELHO   NOME_FREGUESIA  NOME_LOCALIDADE CODIGO_POSTAL
PT2000022152424NT   ALFANDEGA DA FE AGROBOM AGROBOM 5350
PT2000022152424NT   ALFANDEGA DA FE AGROBOM AGROBOM 5350
PT2000022152424NT   ALFANDEGA DA FE AGROBOM AGROBOM 5350
PT2000022152424NT   ALFANDEGA DA FE AGROBOM AGROBOM 5350
PT2000022152424NT   ALFANDEGA DA FE AGROBOM AGROBOM 5350
PT2000022153119LM   ALFANDEGA DA FE ALFANDEGA DA FE ALFANDEGA DA FE 5350
PT2000022153119LM   ALFANDEGA DA FE ALFANDEGA DA FE ALFANDEGA DA FE 5350
PT2000022153119LM   ALFANDEGA DA FE ALFANDEGA DA FE ALFANDEGA DA FE 5350
PT2000022153119LM   ALFANDEGA DA FE ALFANDEGA DA FE ALFANDEGA DA FE 5350

当我将dict追加到我的列表中时,我不知道它是否会出现问题,或者在尝试转换为csv时会出现某种冲突(我不认为是这种情况)。

但正如我说的那样有效,我在调试时得到了我想要的结果,所以我看不出有什么问题。

1 个答案:

答案 0 :(得分:2)

您正在重复将相同字典添加到列表中。 Python容器存储引用,而不是副本,因此您对该字典所做的任何更改都将通过所有这些引用显示。

是的,在下一次循环迭代中更改字典之前打印该字典将不会显示您在下一次迭代中所做的更改。毕竟,您不打印您添加的词典,因此您没有看到这些引用反映了这一变化。

改为添加字典副本:

if inner.has_key('CPE'):
    data.append(inner.copy())

您可以在交互式会话中轻松重现问题:

>>> data = []
>>> inner = {'foo': 'bar'}
>>> data.append(inner)
>>> data
[{'foo': 'bar'}]
>>> inner['foo'] = 'spam'
>>> inner
{'foo': 'spam'}
>>> data  # note that the data list *also* changed!
[{'foo': 'spam'}]
>>> data = []  # start anew
>>> inner = {'foo': 'bar'}
>>> data.append(inner.copy())  # add a (shallow) copy
>>> data
[{'foo': 'bar'}]
>>> inner['foo'] = 'spam'
>>> data
[{'foo': 'bar'}]
>>> data.append(inner.copy())
>>> data
[{'foo': 'bar'}, {'foo': 'spam'}]