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

时间:2016-12-27 13:49:10

标签: 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 reversed(list):
        if element != 0:
            return list.index(element)

但是,当有两个相同的数字时,它不起作用,如上面的第一个示例所示,它返回0,因为-2位于列表的第0和第1位置

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

10 个答案:

答案 0 :(得分:4)

您可以迭代reversed列表并返回第一个不为零的项目,例如

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

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

答案 1 :(得分:3)

您的解决方案会不断更改列表,我认为即使是天真的last_nonzero_index = None for idx, item in enumerate(originalList): if item != 0: last_nonzero_index = idx 循环也更好:

("u'Is", 'JJ', u'O')
('Miami', 'NNP', u'B-PERSON')
('playing', 'NN', u'O')
('in', 'IN', u'O')
('Washigthon', 'NNP', u'B-GPE')
('this', 'DT', u'O')
('month', 'NN', u'O')
('?', '.', u'O')

答案 2 :(得分:2)

这是一个纯粹由生成器组成的版本:没有一个列表被复制。

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

我们的想法是在计算(reversed)时迭代enumerate列表。如果列表全为零,则返回-1

答案 3 :(得分:2)

此问题带有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

答案 4 :(得分: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

我仍然怀疑有更好的方法可以做到这一点,所以请分享您可能拥有的任何其他解决方案。

答案 5 :(得分:1)

这是使用itertools.takewhile()

的pythonic和优化方法
from itertools import takewhile
from operator import not_
len(lst) - sum(1 for _ in takewhile(not_, reversed(lst))) - 1

演示:

In [115]: lst = [-2, -2, 0, 0, 0, 0, 0]
In [118]: len(lst) - sum(1 for _ in takewhile(lambda x : not bool(x), lst[::-1])) - 1
Out[118]: 1

In [119]: lst = [-2, 20, -1, 0, 3, 0, 0]

In [120]: len(lst) - sum(1 for _ in takewhile(lambda x : not bool(x), lst[::-1])) - 1
Out[120]: 4

这是一个基准测试,在更长的列表中有另一个答案:

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

答案 6 :(得分:1)

列表理解起到了作用:

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]

答案 7 :(得分:1)

n_l = []
for i,v in enumerate(l): #enumerate returns the index - i, and value-v
    if v != 0:
        n_l.append(i) #keep the index if the value is not 0

n_l = sorted(n_l) #we then sort the list of indecies from least to greatest. the greatest index will be the last
greatest_non_zero_index = n_l[-1] #grab the last index

另一种方法是在一行中做到这一点!

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

答案 8 :(得分: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

答案 9 :(得分:1)

列表理解的oneliner的另一种方法是找到0的所有ocncence并找到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

这在复杂度O(n)中运行,因为枚举和max具有O(n)运行时。