Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.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_Python 3.x - Fatal编程技术网

Python 如何从排序列表中选择小于给定整数的元素?

Python 如何从排序列表中选择小于给定整数的元素?,python,list,python-3.x,Python,List,Python 3.x,我有素数数组,例如0到1000之间的整数 primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229

我有素数数组,例如0到1000之间的整数

primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
我得到输入

n = int(input())

当数组的最后一个元素小于
n
时,将数组切片到新数组的最有效方法是什么?

您可以利用
素数已排序的事实,如下所示

>>> from bisect import bisect
>>> primes[:bisect(primes, n)]

bisect
对输入列表进行二进制搜索,并返回小于
n

的元素索引。您有一个
列表,而不是数组。如果您确实需要对列表进行切片并构建一个新的列表,那么无论您如何操作,这都需要线性时间。可能是你要做的最好的事情:

small_primes = primes[:bisect.bisect(primes, n)]
如果您有NumPy,它知道如何创建看起来像切片的视图,但实际上引用而不是复制数据。事实上,如果
primes
ndarray
,您可以使用与fourtheye答案完全相同的代码,它将是O(logn)

如果只需要迭代“数组”一次,而不是将其用作列表,则可以使用惰性迭代器:

small_primes = itertools.takewhile(lambda p: p<n, primes)

small_primes=itertools.takewhile(lambda p:p如果您不再需要完整的素数列表,截断素数可能是最快的方法:

primes[bisect(primes, n):]=[]

但与往常一样,如果你在意的话,请衡量它。

你没有解释为什么你要求“最有效的方法”,或者你所说的“时间?空间?其他什么?”是什么意思,我高度怀疑这是否真的是一个值得在任何地方优化的性能瓶颈,但如果它是:

您只有168个元素。而且您不会有很多类似的列表,因此空间不太可能相关。同时,对于N=168的线性算法来说,您必须多次调用它,但只有1000个可能的值。因此,只需预先创建一个表:

prime_slices = [[prime for prime in primes if prime < n] for n in range(1000)]

这是固定的时间。当然设置需要O(N^2)时间,但这没什么,因为它只发生一次,而节省O(N)工作无数次。它需要O(N^2)空间,但实际上这只是一个固定的15K指针,你几乎可以肯定负担得起。

是的,对分需要O(logn)时间。切片需要O(N)然而,时间就像简单的解决方案一样。它只做了平均N/2而不是N,更重要的是,它有一个惊人的快速乘数,因为列表切片大部分只是一个memmove…但它仍然是O(N),而不是O(logn)。如果不使用某种视图类而不是切片,你无法克服这一点。@abamert
primes[bisect](primes,n):]=[]
可能可以做更少的工作,但我对实现的了解还不够sure@tobyodavies好的。我也不确定,但是如果这真的是某人的瓶颈,它是值得测试的。我认为使用某些领域知识甚至更快。考虑素数计数函数π(n)。返回质数@wim:Good point。但是你仍然只是优化O(logn)部分(二分法),使其接近常数,同时仍然保持O(N)部分的线性。实际上这可能是值得的(同样,这是非常快的O(N)…),但我个人不会浪费时间尝试,除非我有一个真正的测试用例,它很重要。当然,这实际上不是“切片数组到新数组”…但是OP没有“数组”首先,所以我不太担心按照字面上的说明去做…这就是我的想法。只有168个值?滥用RAM!+1我们还可以在外部列表中有多个索引指向同一个内部列表。然后你只有168个左右的内部列表和1000个映射到这些内部列表的索引。这将让它更有效率。那是作弊。n=532157328914738291437490372184的中断。@Shashank:是的,我真的应该添加一些东西来显式地“实习”列表,而不是构建每个列表~7次……但我想把它写成一个明显的1行程序。@wim:好的,所以
def prime\u切片(n):\n\ttry:return\u prime\u slices[n]\n\t接受索引器:return prime\u slices[-1]\n
:)但老实说,我认为“我有一个多达1000个素数的列表”和“我想让素数达到任意n”可能会引发n>1000的异常。否则,它会返回误导性的答案…
prime_slices = [[prime for prime in primes if prime < n] for n in range(1000)]
prime_slices[n]