简体   繁体   English

列表中第一次出现(不等式匹配)的索引

[英]index of a first occurrence (inequality match) in a list

A=[2,3,5,7,11,13]
print(A.index(5))

The answer is 2, But what I need is the first one which is bigger than 4 (the answer will be the same - 2).答案是 2,但我需要的是第一个大于 4 的(答案相同 - 2)。 I can apply a while loop, but is there a more elegant or a builtin way to do it?我可以应用一个 while 循环,但是有没有更优雅或内置的方法来做到这一点? In my problem the list is sorted in an ascending order (no duplication), and my target is to split it into two lists: lower or equal to 4, and bigger than 4;在我的问题中,列表按升序排序(不重复),我的目标是将其拆分为两个列表:小于或等于 4,大于 4; and given the list is sorted it would be redundant to scan it twice (or even once).并且鉴于列表已排序,扫描它两次(甚至一次)将是多余的。

As @DanD.mentioned, you can use the bisect module for this, in you example you can use bisect_left 正如@DanD.lied,您可以使用bisect模块,在您的示例中,您可以使用bisect_left

>>> import bisect
>>> bisect.bisect_left(A, 5)
2

This will use a binary search since your data is sorted, which will be faster than a linear search ( O(logN) instead of O(N) ). 这将使用二进制搜索,因为您的数据已排序,这将比线性搜索( O(logN)而不是O(N) )更快。

If you want the index of the first value greater than 4 , then you can switch to bisect_right 如果您希望第一个值的索引大于4 ,则可以切换到bisect_right

>>> bisect.bisect_right(A, 4)
2

You're totally correct about efficiency - if you have already sorted list, do not iterate linearly, its waste of time 你对效率完全正确 - 如果你已经排序列表,不要线性迭代,浪费时间

There's built-in bisect module - exactly for binary search in sorted containers. 有内置的bisect模块 - 完全用于已分类容器中的二进制搜索。

You're probably looking for bisect_right function. 你可能正在寻找bisect_right函数。

Thanks everybody, the answer using your kind help is: 谢谢大家,使用你的帮助的答案是:

import bisect
A=[2,3,5,7,11,13]
N=bisect.bisect_right(A,4)
print(A[:N]) #[2,3]
print(A[N:]) #[5,7,11,13]

Use next with a default argument: 使用next作为默认参数:

val = next((i for i, x in enumerate(A) if x > 4), len(A))

Given the above result, you can then do: 鉴于上述结果,您可以执行以下操作:

left, right = A[:val], A[val:]

List comprehension can do the trick if you want the first occurrence: 如果你想要第一次出现,列表理解可以做到这一点:

A=[2,3,5,7,11,13]
[x > 4 for x in A].index(True)

Out[341]: 2

And to split: 分裂:

[x for x in A if x > 4]
Out[345]: [5, 7, 11, 13]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM