Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 返回列表中最后一个非零元素的索引_Python_List_Numpy - Fatal编程技术网

Python 返回列表中最后一个非零元素的索引

Python 返回列表中最后一个非零元素的索引,python,list,numpy,Python,List,Numpy,我以以下格式获取数据: [-2, -2, 0, 0, 0, 0, 0] [-2, 20, -1, 0, 3, 0, 0] 每一行都是不同的输入。列表可以超过7个元素。我需要返回最后一个非零元素的索引位置,因此: [-2, -2, 0, 0, 0, 0, 0] >>> 1 [-2, 20, -1, 0, 3, 0, 0] >>> 4 以下代码大部分时间都会执行此操作: def getIndex(list): for element in revers

我以以下格式获取数据:

[-2, -2, 0, 0, 0, 0, 0]
[-2, 20, -1, 0, 3, 0, 0]
每一行都是不同的输入。列表可以超过7个元素。我需要返回最后一个非零元素的索引位置,因此:

[-2, -2, 0, 0, 0, 0, 0]
>>> 1
[-2, 20, -1, 0, 3, 0, 0]
>>> 4
以下代码大部分时间都会执行此操作:

def getIndex(list):
    for element in reversed(list):
        if element != 0:
            return list.index(element)
但是,当有两个相同的数字时,它不起作用,如上面的第一个示例所示,该示例返回
0
,因为
-2
同时位于列表的第0和第1位置


那么,即使存在具有相同值的元素,如何获取列表中最后一个非零元素的索引呢?

以下解决方案通过了我所有的测试用例:

def getLastNonZeroIndex(originalList):

    # Create a new list from the old list
    # so changes don't change the old list
    newList = list(originalList)

    # Keep checking to see if last item equals 0
    # If it does, remove it from newList
    while newList[-1] == 0:
        newList.pop()

    # Once the item at newList[-1] != 0
    # Return index of the last element
    return len(newList)-1

我仍然怀疑有更好的方法可以做到这一点,因此请分享您可能有的任何替代解决方案。

您的解决方案会不断更改列表,我认为即使是天真的
for
循环也会更好:

last_nonzero_index = None
for idx, item in enumerate(originalList):
    if item != 0:
        last_nonzero_index = idx

这是一个纯由生成器生成的版本:没有复制您的列表

a = [-2, -2, 0, 0, 0, 0, 0]
b = [-2, 20, -1, 0, 3, 0, 0]

def index_of_last_nonzero(lst):
    for i, value in enumerate(reversed(lst)):
        if value != 0:
            return len(lst)-i-1
    return -1

print(index_of_last_nonzero(lst=a))  # -> 1
print(index_of_last_nonzero(lst=b))  # -> 4

其思想是在计数时迭代
反转的
列表(使用
枚举
)。如果列表全部为零,则返回
-1

您可以迭代
反向
列表,并返回第一个不是零的项,如下所示

>>> def get_last_non_zero_index(d, default=None):
...     rev = (len(d) - idx for idx, item in enumerate(reversed(d), 1) if item)
...     return next(rev, default)
...
>>> print(get_last_non_zero_index([-2, -2, 0, 0, 0, 0, 0]))
1
>>> print(get_last_non_zero_index([-2, 20, -1, 0, 3, 0, 0]))
4
>>> print(get_last_non_zero_index([0, 0, 0]))
None
>>> print(get_last_non_zero_index([]))
None

如果函数找不到非零值,将返回
默认值。

下面是一个使用
itertools.takewhile()的pythonic优化方法:

演示:

下面是一个Benchmark,在较长的列表中还有另一个答案:

In [141]: lst = lst * 1000

In [142]: %timeit len(lst) - len(list(takewhile(not_, reversed(lst)))) - 1
1000000 loops, best of 3: 758 ns per loop

In [143]: %timeit get_last_non_zero_index(lst)
1000000 loops, best of 3: 949 ns per loop

In [146]: %timeit index_of_last_nonzero(lst)
1000000 loops, best of 3: 590 ns per loop

列表理解起到了关键作用:

a = [-2, 20, -1, 0, 3, 0, 0]
ls = [i for i, e in enumerate(a) if e != 0]
print(ls)
输出:

[0, 1, 2, 4]
这里有另一种方法可以做到这一点在一行

greatest_non_zero_index = sorted([i for i,v in enumerate(l) if v != 0])[-1]

以下方面应起作用:

def last_non_zero_index(my_list):
    temp = my_list[:]
    while temp[-1] == 0:
        del temp[-1]
    return len(temp) - 1
输出:

>>> my_list = [-2, -2, 0, 0, 0, 0, 0]
>>> last_non_zero_index(my_list)
1
>>> my_list = [-2, 20, -1, 0, 3, 0, 0]
>>> last_non_zero_index(my_list)
4

具有列表理解功能的oneliner的另一种方法是查找0的所有ocurence,并使用
max()
查找最高索引,如下所示:

a = [1,-2,3,0,2,0,-2,0,0,0]

def get_last_non_zero_idx(my_list):
    return max([index for index, el in enumerate(my_list) if el])

print(get_last_non_zero_idx(a))
>> 6

正如enumerate和max have O(n)运行时一样,这是一个复杂度为O(n)的问题。

这个问题被标记为
numpy
,但我看不到明显的解决方案:

numpy.max(numpy.nonzero(list))
示例以及提供的列表:

>>> import numpy as np
>>> np.max(np.nonzero([-2, -2, 0, 0, 0, 0, 0]))
1
>>> np.max(np.nonzero([-2, 20, -1, 0, 3, 0, 0]))
4

非常好地使用了
next
+1我认为这基本上可以归结为一行:
return[index for index,item in enumerate(lst)if item!=0][1]
这是使用它的主要好处之一。
sorted
对您有什么好处吗?
enumerate
是否已按顺序遍历列表,以便
n_l
已排序?或者甚至从
np.nonzero
获取返回的最后一个元素:
np.nonzero(a)[-1]
a = [1,-2,3,0,2,0,-2,0,0,0]

def get_last_non_zero_idx(my_list):
    return max([index for index, el in enumerate(my_list) if el])

print(get_last_non_zero_idx(a))
>> 6
numpy.max(numpy.nonzero(list))
>>> import numpy as np
>>> np.max(np.nonzero([-2, -2, 0, 0, 0, 0, 0]))
1
>>> np.max(np.nonzero([-2, 20, -1, 0, 3, 0, 0]))
4