user3108489 user3108489 - 20 days ago 9
Python Question

Writing a list to a CSV file

I've got a piece of code that extracts coordinates from a KML file. It works beautifully and prints to the screen the way I'd want it to print to a CSV file. However, when I attempt to write it to a CSV file, the resulting file is empty.

I've tried both the method below and the standard text output method using

.write
and
.writerows
. All have the same result.

Here is the KML I'm using:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<name>Test3.kml</name>
<Style id="s_ylw-pushpin">
<IconStyle>
<scale>1.1</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>
</Icon>
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
</IconStyle>
</Style>
<Style id="s_ylw-pushpin_hl">
<IconStyle>
<scale>1.3</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>
</Icon>
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
</IconStyle>
</Style>
<StyleMap id="m_ylw-pushpin">
<Pair>
<key>normal</key>
<styleUrl>#s_ylw-pushpin</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#s_ylw-pushpin_hl</styleUrl>
</Pair>
</StyleMap>
<Placemark>
<name>Untitled</name>
<styleUrl>#m_ylw-pushpin</styleUrl>
<LineString>
<tessellate>1</tessellate>
<coordinates>
-117.2983479390361,33.27144940863937,0 -117.2979479084534,33.27158154479859,0 -117.2974695164833,33.27172038778199,0 -117.2975027748323,33.27194103134417,0 -117.297514618297,33.27194834552386,0 -117.2979065026131,33.27210103585357,0 -117.2980671096438,33.27197757139673,0 -117.2980506390891,33.27176546338881,0 -117.2983889177018,33.27174732829762,0 -117.2985056013534,33.27196820309105,0 -117.2984607071796,33.27217535203514,0 -117.2982982520078,33.2722451382993,0 -117.2982714656408,33.2722496045722,0 -117.297926137081,33.27225329696987,0 -117.2979181624345,33.27225324047765,0 -117.297660871735,33.27222714260547,0 -117.2976362532899,33.2722186164706,0 -117.2974159727989,33.27218328409937,0 -117.2974081729552,33.27218350960742,0 -117.2970860609136,33.27208829299941,0 -117.2968393500826,33.27207716108421,0 -117.2967459496535,33.27216774204006,0 -117.2966603938058,33.27233920748802,0 -117.2969907889174,33.27237357387524,0 -117.2970232333844,33.27237306198914,0 -117.2973444433226,33.27239693646774,0 -117.297751764355,33.27242613992279,0 -117.2981731050047,33.27243373303686,0 -117.2981813185804,33.27243372905114,0 -117.2985617246156,33.2723816290589,0 -117.2987498163436,33.27248971415388,0 -117.2987694564539,33.27262188734785,0 -117.2985436721398,33.27267540671544,0 -117.2985270445518,33.27267612619851,0 -117.2981490803383,33.27268345629938,0 -117.2981145841072,33.2726829556605,0 -117.2977420026904,33.27265933276826,0 -117.2977334907908,33.27265936075214,0 -117.2977079525845,33.27265943947727,0 -117.297690884793,33.27265933069783,0 -117.2973143742666,33.2726410594433,0 -117.2972972842265,33.27263660852098,0 -117.2972803621663,33.27263663588342,0 -117.2969673713573,33.27262125275644,0 -117.296756583612,33.27260864705382,0 -117.2965634725893,33.27264899681126,0 -117.2965301429721,33.27279607660442,0 -117.296929900768,33.27282274189361,0 -117.2972917056901,33.27281884120617,0 -117.2975482260676,33.27280094439733,0 -117.2979485409129,33.27281652227333,0 -117.2983940432828,33.2728392485114,0 -117.2987809571886,33.27284381722371,0
</coordinates>
</LineString>
</Placemark>
</Document>
</kml>


And the code:

from xml.dom import minidom
import csv

xmldoc = minidom.parse("Test.kml")

kml = xmldoc.getElementsByTagName("kml")[0]

document = kml.getElementsByTagName("Document")[0]

placemarks = document.getElementsByTagName("Placemark")

for placemark in placemarks:
coords = placemark.getElementsByTagName("coordinates")[0].firstChild.data

list = coords.split(",")
for items in list:
item = items.split(",")
for allitems in item:
latlon = allitems.replace("0 ","")
latlon = latlon.strip()
print(latlon) # <-- Printing to the screen works fine
with open("Output.csv", "w") as output:
writer = csv.writer(output, delimiter='\n')
writer.writerow(latlon)


****SOLVED****
Final working solution is this:

with open("Output.csv", "w") as text_file: # open the file first
#writer = csv.writer(output, delimiter='\n') # and get ready to write

for placemark in placemarks:
coords = placemark.getElementsByTagName("coordinates")[0].firstChild.data

list = coords.split(",")
for items in list:
item = items.split(",")
for allitems in item:
latlon = allitems.replace("0 ","")
latlon = latlon.strip()
print(latlon) # <-- Printing to the screen works fine
text_file.write(latlon + '\n') # Write the row to the already-open file


I abandoned the csv method and went with a text file output, just renaming to csv. I end up with the result I need. Thanks to all that contributed.

cxw cxw
Answer

The with and writer= should be happening once, at the beginning of your loop. As it is now, you are re-creating the file for each item, throwing away the last item.

with open("Output.csv", "w") as output:             # open the file first
    writer = csv.writer(output, delimiter='\n')     # and get ready to write

    for placemark in placemarks:
        coords = placemark.getElementsByTagName("coordinates")[0].firstChild.data

        list = coords.split(",")
        for items in list:
            item = items.split(",")
            for allitems in item:
                latlon = allitems.replace("0 ","")
                latlon = latlon.strip()
                print(latlon) # <-- Printing to the screen works fine
                writer.writerow([latlon])     # Write the row to the already-open file
                       # EDIT 2 ^      ^

Edit Now there may be another issue: it looks like latlon is a string, but writerow expects a list of items, and fills in the commas between the items automatically. You might want print(latlon + ',', file=output) instead of writer.writerow depending on your specific use case.

Edit 2 Use [latlon] instead of latlon to get the whole line on one row instead of one character per row. The brackets make it a list of one item rather than a string, which behaves in this context like a list of its characters, one at a time.