문제

park = "a park.shp"
road = "the roads.shp"
school = "a school.shp"
train = "the train"
bus = "the bus.shp"
mall = "a mall"
ferry = "the ferry"
viaduct = "a viaduct"

dataList = [park, road, school, train, bus, mall, ferry, viaduct]

print dataList

for a in dataList:
    print a
    #if a.endswith(".shp"):
     #   dataList.remove(a)

print dataList

gives the following output (so the loop is working and reading everything correctly):

['a park.shp', 'the roads.shp', 'a school.shp', 'the train', 'the bus.shp', 'a mall', 'the ferry', 'a viaduct']
a park.shp
the roads.shp
a school.shp
the train
the bus.shp
a mall
the ferry
a viaduct
['a park.shp', 'the roads.shp', 'a school.shp', 'the train', 'the bus.shp', 'a mall', 'the ferry', 'a viaduct']

but when I remove the # marks to run the if statement, where it should remove the strings ending in .shp, the string road remains in the list?

['a park.shp', 'the roads.shp', 'a school.shp', 'the train', 'the bus.shp', 'a mall', 'the ferry', 'a viaduct']
a park.shp
a school.shp
the bus.shp
the ferry
a viaduct
['the roads.shp', 'the train', 'a mall', 'the ferry', 'a viaduct']

Something else I noticed, it doesn't print all the strings when it's clearly in a for loop that should go through each string? Can someone please explain what's going wrong, where the loop keeps the string road but finds the other strings ending with .shp and removes them correctly?

Thanks, C

(FYI, this is on Python 2.6.6, because of Arc 10.0)

도움이 되었습니까?

해결책

You are mutating the list and causing the index to skip.

Use a list comprehension like this:

[d for d in dataList if not d.endswith('.shp')]

and then get:

>>> ['the train', 'a mall', 'the ferry', 'a viaduct']

다른 팁

Removing items from the same list you're iterating over almost always causes problems. Make a copy of the original list and iterate over that instead; that way you don't skip anything.

for a in dataList[:]: # Iterate over a copy of the list
    print a
    if a.endswith(".shp"):
        dataList.remove(a) # Remove items from the original, not the copy

Of course, if this loop has no purpose other than creating a list with no .shp files, you can just use one list comprehension and skip the whole mess.

no_shp_files = [a for a in datalist if not a.endswith('.shp')]
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top