Creating .csv based on values in dictionary
<p>I'm trying to parse an XML file, return the values and put it into a .csv file. I have the following code so far:</p>

<pre><code>for shift_i in shift_list :

    # Iterates through all values in 'shift_list' for later comparison to ensure all tags are only counted once
    for node in tree.xpath("//Data/Status[@Name and @Reason]"):
    # Iterates through all nodes containing a 'Name' and 'Reason' attribute
        state = node.attrib["Name"]
        reason = node.attrib["Reason"]
        end = node.attrib["End"]
        start = node.attrib[u'Start']
        # Sets each of the attribute values to the name of the attribute all lowercase
        try:
        shift = node.attrib[u'Shift']
        except:
            continue
        # Tries to set shift attribute value to 'shift' variable, sometimes fails if no Shift attribute is present
        if shift == shift_i :
        # If the Shift attribute is equal to the current iteration from the 'shift_list', takes the difference of start and end and appends that value to the list with the given Name, Reason, and Shift
            tdelta = datetime.strptime(end, FMT) - datetime.strptime(start, FMT)
            d[state, reason, shift].append((tdelta.total_seconds()) / 60)

    for node in tree.xpath("//Data/Status[not(@Reason)]"):
    # Iterates through Status nodes with no Reason attribute
        state = node.attrib["Name"]
        end = node.attrib["End"]
        start = node.attrib[u'Start']
        # Sets each of the attribute values to the name of the attribute all lowercase
        try:
            shift = node.attrib[u'Shift']
        except:
            continue
        # Tries to set shift attribute value to 'shift' variable, sometimes fails if no Shift
        #      attribute is present
        if shift == shift_i:
            # If the Shift attribute is equal to the current iteration from the 'shift_list',
            #   takes the difference of start and end and appends that value to the list with
            #   the given Name, "No Reason" string, and Shift
            tdelta = datetime.strptime(end, FMT) - datetime.strptime(start, FMT)
            d[state, 'No Reason', shift].append((tdelta.total_seconds()) / 60)

    for item in d :
     # Iterates through all items of d
        d[item] = sum(d[item])
        # Sums all values related to 'item' and replaces value in dictionary
    a.update(d)
    # Current keys and values in temporary dictionary 'd' to permanent
    #   dictionary 'a' for further analysis
    d.clear()
    # Clears dictionary d of current iterations keys and values to start fresh for next
    #   iteration. If this is not done, d[item] = sum(d[item]) returns
    #   "TypeError: 'float' object is not iterable"
</code></pre>

<p>This creates a dictionary with values that look like this:</p>

<pre><code>{('Name1','Reason','Shift'):Value,('Name2','Reason','Shift'):Value....}
</code></pre>

<p>print(a) returns this</p>

<pre><code>defaultdict(&lt;class 'list'&gt;, {('Test Run', 'No Reason', 'Night'): 5.03825, ('Slow Running', 'No Reason', 'Day'): 10.72996666666667, ('Idle', 'Shift Start Up', 'Day'): 5.425433333333333, ('Idle', 'Unscheduled', 'Afternoon'): 470.0, ('Idle', 'Early Departure', 'Day'): 0.32965, ('Idle', 'Break Creep', 'Day'): 24.754250000000003, ('Idle', 'Break', 'Day'): 40.0, ('Micro Stoppage', 'No Reason', 'Day'): 39.71673333333333, ('Idle', 'Unscheduled', 'Night'): 474.96175, ('Running', 'No Reason', 'Day'): 329.4991500000004, ('Idle', 'No Reason', 'Day'): 19.544816666666666})
</code></pre>

<p>I want to create a .csv that has columns of 'Names'+'Reasons' with the totals, and the rows are described by the 'Shift'. Like this:</p>

<pre><code>         Name1-Reason    Name2-Reason    Name3-Reason    Name4-Reason
Shift1      value          value            value           value
Shift2      value          value            value           value
Shift3      value          value            value           value
</code></pre>

<p>I'm not sure how to go about doing this. I tried using nested Dicts to better describe my data but I got a TypeError when using </p>

<pre><code>d[state][reason][shift].append((tdelta.total_seconds()) / 60)
</code></pre>

<p>If there is a better way to do this please let me know, I'm a very new to this and would love to hear all advice.</p>

<p>I would use the DictWriter method of the csv package to write your csv file. For that you need to have a list of dictionaries. Each list item is a <code>shift</code> and is represented by a dictionary with keys <code>name</code> &amp; <code>reason</code>. It should look like the following:</p>

<p><code>[{'Name1':value1, 'Name2':value2}, {'Name1':value3, 'Name2':value4}]</code></p>

python csv dictionary