简体   繁体   English

在不使用len函数的情况下在Python中查找列表的大小

[英]Find the size of a list in Python without using len function

Recently I attended a Python coding challenge where I was asked to find the size of a list. 最近,我参加了一个Python编码挑战赛,要求我查找列表的大小。

For example if the list is l = [100, 100, 100] then it should return 3. 例如,如果列表为l = [100, 100, 100] ,则应返回3。

The list was termed as a virtual list with unknown number of elements. 该列表被称为元素数量未知的虚拟列表。

There is a getElement() function provided which takes the index as a parameter and returns the value 100 assuming that all the element of the list is 100. 提供了一个getElement()函数,该函数将索引作为参数,并假设列表的所有元素均为100,则返回值100。

def getElement(index):
    ###some exception logic for index out of range
    return 100

So I was asked to write a function def findListSize() which will return the size of the list with condition of only invoking the getElement() function. 因此,我被要求编写一个函数def findListSize() ,该函数将在仅调用getElement()函数的情况下返回列表的大小。 The lower the number of calls to getElement() the more bonus points will be awarded. 调用getElement()的次数越少,将获得更多的奖励积分。

def findListSize():
    array_size = 0

    ###logic here

    return array_size

I was not able to proceed in a right direction to solve the problem. 我无法朝正确的方向解决问题。 Can someone help me? 有人能帮我吗?

If you can only use getElement , then the naive solution would be to call getElement in a loop with increasing indices and count how often it succeeds before it fails. 如果只能使用getElement ,那么幼稚的解决方案是在索引增加的循环中调用getElement并计算失败之前成功的频率。 But this might call getElement very often (once for each element in the list). 但这可能会经常调用getElement (对于列表中的每个元素一次)。

size = 0
try:
    while True:
        getElement(size)
        size += 1
except:
    print("size is", size)

Alternatively, you could first call getElement with exponentially increasing values (eg getElement(2) , getElement(4) , getElement(8) , ...) to determine the magnitude of the list, and once you know a generous upper bound, use binary search to find the exact size. 或者,你可以先打电话getElement与指数增加值(例如getElement(2) getElement(4) getElement(8) ,...),以确定列表的大小,一旦你知道一个慷慨的上限,使用二进制搜索以找到确切的大小。

upper = 2
try:
    while True:
        getElement(upper)
        upper *= 2
except IndexError:
    pass
lower = -1
while lower < upper:
    middle = (lower + upper) // 2 + 1
    try:
        getElement(middle)
        lower = middle
    except IndexError:
        upper = middle - 1
print("size is", lower + 1)

This way, I was able to find the size of a list with 51166 elements (upper bound of 65536) with just 33 calls to getElement . 这样,我只用对getElement 33次调用就能找到具有51166个元素(上限为65536个)的列表的大小。 (I guess you could also get rid of those try/except if you are allowed to write a helper function that tries a certain index and then returns True or False instead of raising an exception.) (我猜您也可以摆脱那些try/except如果允许您编写一个尝试某个索引然后返回TrueFalse而不是引发异常的帮助函数)。

I would try something like binary search (half-interval search) https://en.wikipedia.org/wiki/Binary_search_algorithm . 我会尝试类似二进制搜索(半间隔搜索)的方法https://en.wikipedia.org/wiki/Binary_search_algorithm Start witch some large number and see if it still return 100 or gives exception Out of range. 启动女巫一些大数字,看看它是否仍然返回100或给出超出范围的异常。 Then increase the number or go to its 0.5* value and so on... read the wikipedia post to get notion of the algorithm. 然后增加数量或达到其0.5 *值,依此类推...阅读Wikipedia帖子以了解算法的概念。 You should end up with lower complexity than in the case of complete search. 与完全搜索相比,最终的复杂度应更低。 But the implementation is up to you, it looks like a homework:) 但是实现取决于您,它看起来像是一项家庭作业:)

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

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