2014-04-09 47 views
2

我有一个包含值和一堆None的列表。例如:python找到不是“无”的列表中的最后一个值的索引

a = ['a', 'b', None, 4, 5, None, 5, 4, None, 7, None, None, None, None] 

我正在寻找的方式最快(字符最短编号)进行查找的索引,在这种情况下7,最后非None值。

9应该是输出。

+0

说“最快(最短的代码)”,不清楚你是想要性能最快的方法还是最少的字符数。有时你很幸运,他们是一样的,但往往不是。 – DSM

回答

7

我认为这是很难被击败的东西很明显,如:

def get_last(a): 
    for i, e in enumerate(reversed(a)): 
    if e is not None: 
     return len(a) - i - 1 
    return -1 

注意reversed()只需创建一个反向迭代器,它不会复制列表。而且由于列表访问速度很快,即使是非常大的列表,这也应该足够好。

内部返回中的减法补偿了reversed()导致enumerate()向后移动输入列表的事实,因此循环内部的索引i从结尾处开始。

+0

我觉得这个'next'版本看起来同样不错。 – DSM

+0

@unwind:我做了:-)但答案使用算术而不是简单的“反转(list(枚举))”。 – DSM

+1

@DSM但是这又创建了另一个列表:) – thefourtheye

1

你可以只用一个标志迭代:

target = 0 
for i, val in enumerate(a): 
    if val is not None: 
     target = i 
6

可以使用enumerate函数来获得一个迭代这给当前索引和项目。我们通过reverseda。因此,如果j不是None,我们将返回序列长度与当前索引之间的差异。我们将所有内容都作为生成器表达式来使用,所以我们需要使用next函数来提高它。

print next(len(a) - i for i, j in enumerate(reversed(a), 1) if j is not None) 
# 9 
+0

我宁愿使用'len(a) - i - 1'而不是'enumerate(...,1)',因为我觉得枚举应该从1开始令人困惑。 – njzk2

+0

为了说明所有值都是None的情况,我会在'next'中加上',-1' – njzk2

+1

@ njzk2返回'-1'不是一个好的选择,因为它是Python中的有效列表索引。 – thefourtheye

1

您可以从后面开始,并检查它是否不是无。

x = next(x for x in reversed(seq) if x is not None) 

编辑:我意识到你正在寻找索引,而不仅仅是价值。以上代码仅给出序列中最后一个非无元素的值。

您可以添加一个枚举器来获取索引。

next(len(seq) - i for i, j in enumerate(reversed(seq), 1) if j is not None) 
+2

这会给出值,而不是索引。 – DSM

+0

已修复。我的错。它现在提供了两条信息。也许有人某天只会想要你的编辑答案的值 – Matt

+0

由fourtheye给出,btw – njzk2

2

像这样:

max(index for index, item in enumerate(a) if item is not None) 
+0

如果所有的值都是无的 – njzk2

+0

当你传递无满的列表时它应该引发异常。这是Pythonic。 –

+1

如果我不得不坐下来阅读所有这些内容而不知道实际问题是什么,这对我来说最为清晰 –

1

试试这个,

>>> a = ['a', 'b', None, 4, 5, None, 5, 4, None, 7, None, None, None, None] 
>>> last_index=0 
>>> for index, i in enumerate(a): 
    if i is not None: 
     last_index= index 


>>> last_index 
9 
>>> 
+0

@ njzk2请参阅更新。如果列表中存在多次7,则 – fledgling

2

使用reduce

a = ['a', 'b', None, 4, 5, None, 5, 4, None, 7, None, None, None, None] 

reduce(lambda n, i : i if a[i] is not None else n, range(0, len(a)), -1) 
1

唐诺ID这样的东西添加到答案的电流池:

>>> a = ['a', 'b', None, 4, 5, None, 5, 4, None, 7, None, None, None, None] 
>>> [i for i,v in enumerate(a) if v is not None][-1] 
9 
>>> 
+0

不起作用。 – njzk2

+0

啊是的非常真实,编辑 – Harpal

+0

你应该使用'is not None'来反对'!= None' [pep8](http://legacy.python.org/dev/peps/pep-0008/)编程建议。 “像None这样的单身人士的比较应该总是用”是“或”不是“,而不是平等运算符。” – Scott

相关问题