将列表写入CSV文件

4
我有一段代码可以从KML文件中提取坐标。它可以很好地将结果打印到屏幕上,就像我想要打印到CSV文件中的那样。但是,当我尝试将其写入CSV文件时,生成的文件为空。
我尝试使用以下方法和标准文本输出方法(使用.write和.writerows),但结果都相同。
这是我正在使用的KML文件:
<?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>

以下是代码:

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)

****问题已解决**** 最终可行的解决方案如下:

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

我放弃了使用csv方法,改成了文本文件输出,只是将其重命名为csv。最终获得了所需的结果。感谢所有做出贡献的人。


2
你意识到每次循环都在(覆盖)写模式下重新打开文件? - jonrsharpe
jonrsharpe和Oliver W. 你们信不信,我在这里之前已经尝试了几种不同的排列方式。你们两个都对只打开一次文件是正确的。这是一个明显的错误。 - user3108489
1个回答

4
< p > 在循环开始时,withwriter=应该只发生一次。目前,你为每个项目重新创建文件,丢掉了最后一个项目。< /p >
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 ^      ^

编辑 现在可能存在另一个问题:看起来latlon是一个字符串,但是writerow期望一列表项,并自动填充项之间的逗号。根据您的具体用例,您可能需要使用print(latlon + ',', file=output)而不是writer.writerow

编辑2 使用[latlon]而不是latlon,以便一行上获得整个行而不是每行一个字符。方括号将其变成一个列表项,而不是一个字符串,在此上下文中,它的行为类似于其每次一个字符的列表项。


请在编辑后跟随代码。 - jonrsharpe
2
但是那样他们就不会得到第一个答案了。 ;) - Brian Cain
@cxw,这最终让我达到了我需要的目标。谢谢你。你的示例原封不动地将列表中每个项目的每个字符放在新行中。此外,print(latlon + ',', file=output)导致无效的语法错误,突出显示"="。 - user3108489

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接