直到它,我正在尝试迭代python中的坐标对列表并删除其中一个坐标为负的所有情况。例如:
数组中的:
map = [[-1, 2], [5, -3], [2, 3], [1, -1], [7, 1]]
我想删除其中任何一个坐标都是< 0,离开:
map = [[2, 3], [7, 1]]
我的问题是python列表没有任何空白,所以如果我像这样循环:
i = 0
for pair in map:
for coord in pair:
if coord < 0:
del map[i]
i += 1
当元素被删除时,所有索引都会移位,弄乱迭代并导致各种问题。我已经尝试将坏元素的索引存储在另一个列表中,然后循环并删除这些元素,但我遇到了同样的问题:一旦消失,整个列表就会移动,索引也不再准确。
有什么我想念的吗?
感谢。
答案 0 :(得分:3)
您可以使用list comprehension:
>>> mymap = [[-1, 2], [5, -3], [2, 3], [1, -1], [7, 1]]
>>> mymap = [m for m in mymap if m[0] > 0 and m[1] > 0]
>>> mymap
[[2, 3], [7, 1]]
答案 1 :(得分:3)
如果列表不大,那么最简单的方法是创建一个新列表:
In [7]: old_map = [[-1, 2], [5, -3], [2, 3], [1, -1], [7, 1]]
In [8]: new_map=[[x,y] for x,y in a_map if not (x<0 or y<0)]
In [9]: new_map
Out[9]: [[2, 3], [7, 1]]
如果您想丢弃其他对,可以使用old_map = new_map
进行此操作。
如果列表太大,创建一个可比较大小的新列表是一个问题,那么你可以就地删除列表中的元素 - 诀窍是先从尾端删除它们:
the_map = [[-1, 2], [5, -3], [2, 3], [1, -1], [7, 1]]
for i in range(len(the_map)-1,-1,-1):
pair=the_map[i]
for coord in pair:
if coord < 0:
del the_map[i]
print(the_map)
产量
[[2, 3], [7, 1]]
PS。 map是一个非常有用的内置Python函数。最好不要命名变量map
,因为这会覆盖内置函数。
答案 2 :(得分:1)
如果您没有对map
列表的任何其他引用,列表理解效果最佳:
map = [[a,b] for (a,b) in map if a > 0 and b > 0]
如果您确实有其他参考资料,并且需要实际删除map
引用的列表中的元素,则必须迭代map
的副本:
for coord in map[:]:
if coord[0] < 0 or coord[1] < 0:
map.remove(coord)
答案 3 :(得分:0)
如果您希望在不创建新列表的情况下执行此操作,只需使用索引从len(map)-1下降到0的for循环。
for index in range(len(map)-1,-1,-1):
if hasNegativeCoord(map[index]):
del(map[index])
我承认,这不是Pythonic。
答案 4 :(得分:0)
就个人而言,我更喜欢就地修改:
li = [[-1, 2], [5, -3], [2, 3], [1, -1], [7, 1]]
print li,'\n'
N = len(li)
for i,(a,b) in enumerate(li[::-1], start=1):
if a<0 or b<0:
del li[N-i]
print li
- &GT;
[[-1, 2], [5, -3], [2, 3], [1, -1], [7, 1]]
[[2, 3], [7, 1]]
答案 5 :(得分:0)
如果列表足够小,那么制作一个只包含您需要的元素的副本会更有效,详见其他答案。
但是,如果列表太大,或者由于某些其他原因需要从列表对象中删除元素,我发现以下小帮助函数非常有用:< / p>
def filter_in_place(func, target, invert=False):
"remove all elements of target where func(elem) is false"
pos = len(target)-1
while pos >= 0:
if (not func(target[pos])) ^ invert:
del target[pos]
pos -= 1
在您的示例中,可以按如下方式应用:
>>> data = [[-1, 2], [5, -3], [2, 3], [1, -1], [7, 1]]
>>> def is_good(elem):
return elem[0] >= 0 and elem[1] >= 0
>>> filter_in_place(is_good, data)
>>> data
[[2, 3], [7, 1]]
(这只是一个面向列表的filter_in_place版本,支持所有基本Python数据类型的版本有点复杂)。
答案 6 :(得分:0)
itertools.ifilter()/ifilterfalse()
存在这样做:通过谓词过滤可迭代(显然不是就地)。
更好的是,如果可能的话,避免创建和分配整个过滤的列表对象,只需迭代它:
import itertools
l = [(4,-5), (-8,2), (-2,-3), (4,7)]
# Option 1: create a new filtered list
l_filtered = list( itertools.ifilter(lambda p: p[0]>0 and p[1]>0, l) )
# Option 2:
for p in itertools.ifilter(lambda p: p[0]>0 and p[1]>0, l):
... <subsequent code on your filtered list>
答案 7 :(得分:-2)
您可能需要del pair
。