Python:删除满足特定条件的所有列表索引

发布于 2024-12-01 03:47:35 字数 555 浏览 1 评论 0原文

为了直接解决这个问题,我试图迭代 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

当元素被删除时,所有索引都会移动,搞乱迭代并导致各种问题。我尝试将坏元素的索引存储在另一个列表中,然后循环并删除这些元素,但我遇到了同样的问题:一旦一个元素消失,整个列表的移位和索引就不再准确。

我有什么遗漏的吗?

谢谢。

to get right down to it, I'm trying to iterate through a list of coordinate pairs in python and delete all cases where one of the coordinates is negative. For example:

in the array:

map = [[-1, 2], [5, -3], [2, 3], [1, -1], [7, 1]]

I want to remove all the pairs in which either coordinate is < 0, leaving:

map = [[2, 3], [7, 1]]

My problem is that python lists cannot have any gaps, so if I loop like this:

i = 0
for pair in map:
        for coord in pair:
            if coord < 0:
                del map[i]
    i += 1

All the indices shift when the element is deleted, messing up the iteration and causing all sorts of problems. I've tried storing the indices of the bad elements in another list and then looping through and deleting those elements, but I have the same problem: once one is gone, the whole list shifts and indices are no longer accurate.

Is there something I'm missing?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

避讳 2024-12-08 03:47:36

您可以使用 列表理解 来实现此目的:

>>> 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]]

You can use list comprehension for this:

>>> 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]]
清泪尽 2024-12-08 03:47:36

如果您没有对 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)

If you do not have any other references to the map list, a list comprehension works best:

map = [[a,b] for (a,b) in map if a > 0 and b > 0]

If you do have other references and need to actually remove elements from the list referenced by map, you have to iterate over a copy of map:

for coord in map[:]:
    if coord[0] < 0 or coord[1] < 0:
        map.remove(coord)
凉墨 2024-12-08 03:47:36

就我个人而言,我更喜欢就地修改:

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

->

[[-1, 2], [5, -3], [2, 3], [1, -1], [7, 1]] 

[[2, 3], [7, 1]]

Personally, I prefer in-place modification:

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

->

[[-1, 2], [5, -3], [2, 3], [1, -1], [7, 1]] 

[[2, 3], [7, 1]]
伴我心暖 2024-12-08 03:47:36

如果您希望就地执行此操作,而不创建新列表,只需使用索引从 len(map)-1 到 0 运行的 for 循环即可。

for index in range(len(map)-1,-1,-1):
    if hasNegativeCoord(map[index]):
        del(map[index])

我承认,这不是很 Pythonic。

If you wish to do this in place, without creating a new list, simply use a for loop with index running from len(map)-1 down to 0.

for index in range(len(map)-1,-1,-1):
    if hasNegativeCoord(map[index]):
        del(map[index])

Not very Pythonic, I admit.

草莓味的萝莉 2024-12-08 03:47:36

如果列表足够小,则制作仅包含所需元素的副本会更有效,如其他答案中详述。

但是,如果列表太大,或者由于某些其他原因您需要从列表对象中删除元素就地,我发现以下小辅助函数非常有用:

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 数据类型的版本稍微复杂一些)。

If the list is small enough, it's more efficient to make a copy containing just the elements you need, as detailed in the other answers.

However, if the list is too large, or for some other reason you need to remove the elements from the list object in place, I've found the following little helper function quite useful:

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

In your example, this could be applied as follows:

 >>> 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]]

(This is just a list-oriented version of filter_in_place, one which supports all base Python datatypes is a bit more complex).

心在旅行 2024-12-08 03:47:36

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> 

itertools.ifilter()/ifilterfalse() exist to do exactly this: filter an iterable by a predicate (not in-place, obviously).
Better still, avoid creating and allocating the entire filtered list object if at all possible, just iterate over it:

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> 
东走西顾 2024-12-08 03:47:36

您可能需要delpair

You probably want del pair instead.

浊酒尽余欢 2024-12-08 03:47:35

如果列表不大,那么最简单的方法是创建一个新列表:

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,因为这会覆盖内置变量。

If the list is not large, then the easiest way is to create a new list:

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]]

You can follow this up with old_map = new_map if you want to discard the other pairs.

If the list is so large creating a new list of comparable size is a problem, then you can delete elements from a list in-place -- the trick is to delete them from the tail-end first:

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)

yields

[[2, 3], [7, 1]]

PS. map is such a useful built-in Python function. It is best not to name a variable map since this overrides the built-in.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文