我一直在寻找最有效的方法来获取其中包含最多元素的子数组的索引。例如:
array = [[a,b,c],[a,b],[a,b,c,d,e,f]]
我应该得到的答案是 2。
如何在不使用冗长的 for 循环过程来检查每个 block 的情况下获取它的索引?也不使用 Numpy。
请您参考如下方法:
>>> l = [[1,2,3], [4,5], [6,7,8,9,10]]
>>> max(enumerate(l), key=lambda sub: len(sub[1]))[0]
2
这将返回具有最大项目数(可能不止一个)的元素的最低索引。
展开正在发生的事情:
>>> list(enumerate(l))
[(0, [1, 2, 3]), (1, [4, 5]), (2, [6, 7, 8, 9, 10])]
-> 可迭代的(索引,值)对。
>>> max(enumerate(l), key=lambda sub: len(sub[1]))
(2, [6, 7, 8, 9, 10])
-> 具有最长值(子列表)的(索引,值)对。
>>> max(enumerate(l), key=lambda sub: len(sub[1]))[0]
2
-> 只是索引。
更具可读性的替代方案,但在最坏的情况下对数据进行两次完整传递:
>>> l.index(max(l, key=len))
2
一些省力的时间安排:
In [1]: l = [[0]*i for i in range(10000)]
In [2]: %timeit max(enumerate(l), key=lambda sub: len(sub[1]))[0]
2.05 ms ± 5.95 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [3]: %timeit l.index(max(l, key=len))
791 µs ± 4.22 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
看起来第二个版本更快,即使对于具有 10000 个元素且最后一个元素最长的列表也是如此。这可能是因为只调用了非常高效的内置函数而不是自定义 lambda。
结论:
使用l.index(max(l, key=len))。
(最终编辑:如果您碰巧有一个包含对象的列表,其中调用 index 会触发一些非常昂贵的 __eq__ 检查。)
/p>
