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

时间:2017-08-04 08:06:15

标签: python

最近我参加了一个Python编码挑战,我被要求查找列表的大小。

例如,如果列表为l = [100, 100, 100],则应返回3.

该列表被称为具有未知数量元素的虚拟列表。

提供了getElement()函数,它将索引作为参数,并返回值100,假设列表的所有元素都是100。

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

因此我被要求编写一个函数def findListSize(),该函数将返回列表的大小,条件是仅调用getElement()函数。拨打getElement()的次数越少,奖励积分就越多。

def findListSize():
    array_size = 0

    ###logic here

    return array_size

我无法朝着正确的方向前进来解决问题。有人能帮助我吗?

2 个答案:

答案 0 :(得分:3)

如果你只能使用getElement,那么天真的解决方案就是在循环中调用getElement并增加索引,并计算它失败前的成功频率。但这可能会经常调用getElement(对于列表中的每个元素一次)。

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

或者,您可以先使用指数增加的值(getElementgetElement(2)getElement(4),...)调用getElement(8)来确定列表的大小,一旦你知道一个慷慨的上限,使用binary search来找到确切的大小。

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)

通过这种方式,我能够找到包含51166个元素(上限为65536)的列表大小,只需33次调用getElement。 (如果允许您编写一个尝试某个索引的辅助函数,然后返回try/exceptTrue而不是引发异常,我猜你也可以摆脱那些False。)

答案 1 :(得分:1)

我会尝试二分搜索(半间隔搜索)https://en.wikipedia.org/wiki/Binary_search_algorithm。启动一些大数字,看它是否仍然返回100或异常超出范围。然后增加数字或转到它的0.5 *值等等...阅读维基百科帖子以获得算法的概念。与完全搜索的情况相比,最终的复杂性应该更低。但实施取决于你,看起来像是一个功课:)