简体   繁体   中英

Iterating through a list or tuple?

I've got some coordinates stored as a list. I'm iterating over the list and I want to write the coordinates in a KML file. So I should end up with something resembling the following:

<coordinates>-1.59277777778, 53.8271055556</coordinates>
<coordinates>-1.57945488999, 59.8149016457</coordinates>
<coordinates>-8.57262235411, 51.1289412359</coordinates>

The problem i've got is that my code results in the first item in the list being duplicated three times:

 <coordinates>-1.59277777778, 53.8271055556</coordinates>
 <coordinates>-1.59277777778, 53.8271055556</coordinates>
 <coordinates>-1.59277777778, 53.8271055556</coordinates>

I think I know why it's happening, because the script sees the .strip line and prints the first item in the list 3 times.

Here is my code:

oneLat = ['53.8041778', '59.8149016457', '51.1289412359']
oneLong = ['1.5192528', '1.57945488999', '8.57262235411']

with open("file",'w') as f:
            f.write('''<?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>TracePlace</name>
    <open>1</open>
    <Style id="Photo">
        <IconStyle>
            <Icon>
                <href>../pics/icon.jpg</href>
            </Icon>
        </IconStyle>
        <LineStyle>
            <width>0.75</width>
        </LineStyle>
    </Style>
<Folder>''')    

coord_pairs = zip(map(float, oneLong), map(float, oneLat))
itemsInListOne = int(len(oneLat))

iterations = itemsInListOne

num = 0

while num < iterations:
    num = num + 1
    for coord in coord_pairs:
        print (str(coord).strip('()'))
        f.write("\t\t<coordinates>" + "-" + (str(coord).strip('()')) + "</coordinates>\n")
        break

f.write('''
</Folder>
        </Document>
        </kml>''')
f.close()

How can I get the correct 'mapped' coordinates to write to the KML file? By the 'correct' coordinates, I mean like my first example

Thanks

The problem is with your break line. You break out of the coordPair loop after only the first iteration. Your while loop runs len(coordPairs)==3 times so the 1st item is repeated 3 times.

Here is your code with some improvements (annotated):

oneLat = ['53.8041778', '59.8149016457', '51.1289412359']
oneLong = ['1.5192528', '1.57945488999', '8.57262235411']

# Do the negation here, instead of in the string formatting later
coordPairs = zip((-float(x) for x in oneLong), (float(x) for x in oneLat))

with open("file",'w') as f:
    f.write(xmlHeaderStuff) # I've left out your string literal for brevity    

    #I assume the purpose of the two loops, the while loop and for loop,
    #is for the purpose of repeating the group of 3 coord pairs each time?

    for i in range(len(coordPairs)):
        for coord in coordPairs:
            f.write("\t\t<coordinates>{}, {}</coordinates>\n".format(*coord))
            # break <-- this needs to go

    f.write(xmlFooterStuff)

# f.close() <-- this is unnecessary, since the `with` block takes care of
# file closing automatically

Why would you over complicate things so much? You introduced some weird num iteration counter and not used it at all. I am not gonna debug your code as it feels too bloated, but give you something to work on.

You can simply iterate over the zip object like this:

oneLat = ['53.8041778', '59.8149016457', '51.1289412359']
oneLong = ['1.5192528', '1.57945488999', '8.57262235411']


coord_pairs = zip(oneLong, oneLat)
for coord in coord_pairs:
    print( "{}, {}".format(coord[0], coord[1]) )

Ouput seems fine:

1.5192528, 53.8041778
1.57945488999, 59.8149016457
8.57262235411, 51.1289412359

I think you should be able wrap it up back with writing to file.

EDIT: OK, I figured out what was wrong. This while iterated 3 times over coord_pairs , but the loop has break inside, so it stops at 1st element of coord_pairs . This is why the 1st pair is repeated 3 times. Sorry to be frank but the code looks like Coding Under Influence.

Not sure why you're converting your input strings to floats, just so you can turn them into strings again. Here's a one liner to get a list of those strings:

['<coordinates>-{}, {}</coordinates>'.format(*pair) for pair in zip(oneLong, oneLat)]

Breaking it down...

The zip() returns tuples of (long, lat) pairs.

The [ ] comprehension consumes the zip, creating an element for the left hand part.

The left hand part uses the format() function to fill in the template with your strings.

The *pair expands the the tuple that comes back from the zip() so each member of that tuple is seen as an individual argument. If you don't care for that style of comprehension, you could be more explicit:

['<coordinates>-{}, {}</coordinates>'.format(long, lat) for long, lat in zip(oneLong, oneLat)]

If you have a lot of these, you'd be better of to replace the [list comprehension] with parens, which will just make it an iterator, so you don't have to create an intermediate list. Then you could do something like:

lines = ('<coordinates>-{}, {}</coordinates>\n'.format(*pair) for pair in zip(longIter, latIter))
with open('yourFile', 'w') as file:
    for line in lines:
        file.write(line)

longIter and latIter can be lists, or other forms of iterables.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM