dpd
dpd

Reputation: 187

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.

For example if the list is l = [100, 100, 100] then it should return 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.

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. The lower the number of calls to getElement() the more bonus points will be awarded.

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?

Upvotes: 0

Views: 1274

Answers (2)

tobias_k
tobias_k

Reputation: 82949

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. But this might call getElement very often (once for each element in the list).

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

Alternatively, you could first call getElement with exponentially increasing values (e.g. 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.

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. (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.)

Upvotes: 4

Radek Hofman
Radek Hofman

Reputation: 527

I would try something like binary search (half-interval search) 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. Then increase the number or go to its 0.5* value and so on... read the wikipedia post to get notion of the algorithm. 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:)

Upvotes: 1

Related Questions