How do I not declare a variable in a loop in Python when I have an except argument
<p>I am trying to iterate through all of the rows on the xml list and write those to csv I need each element value, if it exists, to be written, pipe delimited into the row, or else display a null value. I am able to create the header row and write in the first row of data by using variables, (which is obviously incorrect, but I am very new to python!) Any assistance is appreciated!  By the way, please feel free to add anything specific which I could be doing more efficiently or pythonic.</p>

<pre><code>import xml.etree.ElementTree as ET
import sys
import requests
from requests_ntlm import HttpNtlmAuth
import csv

csv.register_dialect(
    'mydialect',
    delimiter = '|',
    quotechar = '"',
    doublequote = True,
    skipinitialspace = True,
    lineterminator = '\n',
    quoting = csv.QUOTE_MINIMAL)

url="http://sharepoint/projects/urp/_vti_bin/owssvr.dll?Cmd=Display&amp;List={8e2de4cf-79a0-4267-8b84-889a5b890b28}&amp;XMLDATA=TRUE"
#url="http://sharepoint/projects/urp/Lists/HITS%20Estimation%20LOE/AllItems.aspx"
password = "#######"
Username = "YYYY\\XXXXX"
server_url="http://sharepoint/"

r=requests.get(url, auth=HttpNtlmAuth(Username,password))
data=r.content

tree = ET.fromstring(data) # load the string into a native XML structure

namespaces = {'s': 'uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882','dt': 'uuid:C2F41010-65B3-11d1-A29F-00AA00C14882', 'rs': 'urn:schemas-microsoft-com:rowset', 'z': '#RowsetSchema'}

header_results = tree.findall('./s:Schema/s:ElementType/s:AttributeType', namespaces)
row_results = tree.findall('./rs:data/z:row', namespaces)

with open('c:\output.csv','w') as f:
    writer = csv.writer(f, dialect='mydialect')

#This causes the column name to be pipe delimited across the top row of the csv
    Header_Row=""
    for header in header_results:
        try:
            Header_Row += header.attrib['name']+"|"
        except KeyError:
            Header_Row += "NULL|"
    writer.writerow([Header_Row])

#This part needs help - I need each element value, if it exists, to be written, pipe delimited into the row, or else display a null value
#Currently this only returns one row of data because I am declaring the variable in the loop... how do I accomplish this otherwise?
    for result in row_results:
        try:
            urpid = result.attrib['ows_CnELookup_x003a_URPID']
        except KeyError:
            urpid = "NULL"
        try:
            Attachments = result.attrib['ows_Attachments']
        except KeyError:
            Attachments = "NULL"
        try:
            Title = result.attrib['ows_LinkTitle']
        except KeyError:
            Title = "NULL"
        try:
            Area = result.attrib['ows_Area_x0020_Name']
        except KeyError:
            Area = "NULL"
        try:
            Group = result.attrib['ows_Group']
        except KeyError:
            Group = "NULL"
        try:
            HITS_Hours = result.attrib['ows_HITS_x0020_Hours']
        except KeyError:
            HITS_Hours = "NULL"
        try:
            Consult_Hours = result.attrib['ows_Consultant_x0020_Hours']
        except KeyError:
            Consult_Hours = "NULL"
        try:
            Complete = result.attrib['ows_C_x0026_E_x0020_Completed']
        except KeyError:
            Complete = "NULL"
        try:
            Area_Order = result.attrib['ows_Area_x0020_Order']
        except KeyError:
            Area_Order = "NULL"
    SP_Row = urpid, Attachments, Title, Area, Group, HITS_Hours, Consult_Hours, Complete, Area_Order
    writer.writerow(SP_Row)
</code></pre>

<p>Actually, if you indent the last two lines one level, I think you'd have what you're looking for.  Your comment in the code mentions "declaring the variable in the loop", but Python variables aren't declared - the only rule is that they must be defined before they are used, which is what you are doing.</p>

<p>As far as a more pythonic way of doing things, the <code>try: ... except KeyError:</code> blocks aren't really the way things are usually done - if you need to get either a stored or default value from a dictionary (named <code>d</code>, for example), use <code>value = d.get(name, default)</code> instead.</p>

<p>Additionally, it looks to me like your header will have an extra <code>|</code> at the end - I'd use this instead:</p>

<pre><code>    Header_Row = [ header.attrib.get('name', 'NULL') for header in header_results ]
    writer.writerow(Header_Row)
</code></pre>

<p>In place of your loop over the result rows, I'd use the following code:</p>

<pre><code>    for results in row_results:
        SP_ROW = [  result.attrib.get(key, 'NULL')
                    for key in [ 'ows_CnELookup_x003a_URPID', 'ows_Attachments',
                                 'ows_LinkTitle', 'ows_Area_x0020_Name', 'ows_Group',
                                 'ows_HITS_x0020_Hours', 'ows_Consultant_x0020_Hours',
                                 'ows_C_x0026_E_x0020_Completed', 'ows_Area_x0020_Order' ] ]
        writer.writerow(SP_ROW)
</code></pre>

<p>Your context manager will make sure the output file is closed, so that should be all you need.</p>

python xml list loops csv