在 geojson 文件中删除带有 for 循环的元素
delete an element with a for loop in a geojson file
对于 .geojson lambda 文件:
{ "type": "FeatureCollection",
"features": [
{ "type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [102.0, 0.5]
},
"properties": {
"label": "value0",
...
}
},
{ "type": "Feature",
"geometry": {..
我想删除“Point”和“Polygon”甚至“MultiPolygon”类型的结构,它们在 properties
中有一个键 'label'
。
import json
file = open('file.geojson', 'r')
data = json.load(file)
for k in data['features']:
if 'label' in k['properties']:
print('ok') #displays the right number of structure, so the loop works
del k #doesn't work
#data['features'].remove(k) works but delete only a part of elements in the file..
print('okk') #displays so del doesn't work
data_srt = open('file.geojson', 'w')
data_srt.write(json.dumps(data, ensure_ascii=False, indent=2))
data_srt.close()
这些解决方案不起作用,为什么?非常感谢。
考虑这个例子:
l = [1, 2, 3]
for i in l:
l.remove(i)
print(l) # Prints '[2]'
在第一次迭代期间 i == l[0]
。 l.remove(i)
将与 l.remove(l[0])
相同。在第二次迭代期间,i == l[1]
。不过此时,l == [2, 3]
,因为 l[0]
已被删除。因此,在第二次迭代中,l.remove(i)
与 l.remove(l[1])
相同。执行后,l == [2]
。如果循环试图继续第三次迭代,i == l[2]
。但是,现在 l == [2]
、len(l) == 1
所以 l[2]
是越界的。因此,for
循环现在停止,即使 l
不为空。这基本上与您遇到的问题相同。
解决这个问题:
i = len(l) - 1
while i >= 0:
l.remove(l[i])
i -= 1
像这样向后迭代列表避免了之前遇到的越界问题。
要在您的情况下应用这个概念,这就是解决方案:
i = len(data["features"]) - 1
while i >= 0:
if "label" in data["features"][i]["properties"]:
data["features"].pop(i)
i -= 1
我刚刚想出一个新的、更好的解决方案(它使用 reversed()
函数):
for k in reversed(data["features"]):
if "label" in k["properties"]:
data["features"].remove(k)
这使用了相同的向后迭代概念,但 reversed()
函数会为您处理。
del
语句对您不起作用的原因是由一个更复杂的概念引起的。我会尽力解释(这是另一个有助于解释它的答案:)。
在 for
循环中遍历列表或任何容器时,如下所示:
l = [1, 2, 3]
for i in l:
del i
i
变量是 l
中某项的深度 副本,不是引用 .在这种情况下,del i
只会删除复制的项目,不会从 l
.
中删除原始项目
另一方面,在这个例子中:
l = [1, 2, 3]
for i in range(len(l)):
del l[i]
del l[i]
将删除 l
中的原始项目,因为 l[i]
returns 原始 对象,不是副本。
不过,在此示例中,您会遇到与以前相同的越界问题,因此使用 del
语句的有效 解决方案是:
for k in reversed(range(len(data["features"]))):
if "label" in data["features"][k]["properties"]:
del data["features"][k]
对于 .geojson lambda 文件:
{ "type": "FeatureCollection",
"features": [
{ "type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [102.0, 0.5]
},
"properties": {
"label": "value0",
...
}
},
{ "type": "Feature",
"geometry": {..
我想删除“Point”和“Polygon”甚至“MultiPolygon”类型的结构,它们在 properties
中有一个键 'label'
。
import json
file = open('file.geojson', 'r')
data = json.load(file)
for k in data['features']:
if 'label' in k['properties']:
print('ok') #displays the right number of structure, so the loop works
del k #doesn't work
#data['features'].remove(k) works but delete only a part of elements in the file..
print('okk') #displays so del doesn't work
data_srt = open('file.geojson', 'w')
data_srt.write(json.dumps(data, ensure_ascii=False, indent=2))
data_srt.close()
这些解决方案不起作用,为什么?非常感谢。
考虑这个例子:
l = [1, 2, 3]
for i in l:
l.remove(i)
print(l) # Prints '[2]'
在第一次迭代期间 i == l[0]
。 l.remove(i)
将与 l.remove(l[0])
相同。在第二次迭代期间,i == l[1]
。不过此时,l == [2, 3]
,因为 l[0]
已被删除。因此,在第二次迭代中,l.remove(i)
与 l.remove(l[1])
相同。执行后,l == [2]
。如果循环试图继续第三次迭代,i == l[2]
。但是,现在 l == [2]
、len(l) == 1
所以 l[2]
是越界的。因此,for
循环现在停止,即使 l
不为空。这基本上与您遇到的问题相同。
解决这个问题:
i = len(l) - 1
while i >= 0:
l.remove(l[i])
i -= 1
像这样向后迭代列表避免了之前遇到的越界问题。
要在您的情况下应用这个概念,这就是解决方案:
i = len(data["features"]) - 1
while i >= 0:
if "label" in data["features"][i]["properties"]:
data["features"].pop(i)
i -= 1
我刚刚想出一个新的、更好的解决方案(它使用 reversed()
函数):
for k in reversed(data["features"]):
if "label" in k["properties"]:
data["features"].remove(k)
这使用了相同的向后迭代概念,但 reversed()
函数会为您处理。
del
语句对您不起作用的原因是由一个更复杂的概念引起的。我会尽力解释(这是另一个有助于解释它的答案:)。
在 for
循环中遍历列表或任何容器时,如下所示:
l = [1, 2, 3]
for i in l:
del i
i
变量是 l
中某项的深度 副本,不是引用 .在这种情况下,del i
只会删除复制的项目,不会从 l
.
另一方面,在这个例子中:
l = [1, 2, 3]
for i in range(len(l)):
del l[i]
del l[i]
将删除 l
中的原始项目,因为 l[i]
returns 原始 对象,不是副本。
不过,在此示例中,您会遇到与以前相同的越界问题,因此使用 del
语句的有效 解决方案是:
for k in reversed(range(len(data["features"]))):
if "label" in data["features"][k]["properties"]:
del data["features"][k]