Alex Kamphuis
Alex Kamphuis

Reputation: 68

find lists that start with items from another list

I have a manifold of lists containing integers. I store them in a list (a list of lists) that I call biglist.

Then I have a second list, eg [1, 2].

Now I want to find all lists out of the big_list that start with the same items as the small list. The lists I want to find must have at least all the items from the second list.

I was thinking this could be done recursively, and came up with this working example:

def find_lists_starting_with(start, biglist, depth=0):
    if not biglist:  # biglist is empty
        return biglist

    try:
        new_big_list = []
        # try:
        for smallist in biglist:
            if smallist[depth] == start[depth]:
                if not len(start) > len(smallist):
                    new_big_list.append(smallist)

        new_big_list = find_lists_starting_with(start,
                                                new_big_list,
                                                depth=depth+1)
        return new_big_list
    except IndexError:
        return biglist

biglist = [[1,2,3], [2,3,4], [1,3,5], [1, 2], [1]]
start = [1, 2]

print(find_lists_starting_with(start, biglist))

However I am not very satisfied with the code example.

Do you have suggestions as how to improve: - understandability of the code - efficiency

Upvotes: 0

Views: 55

Answers (3)

charlierproctor
charlierproctor

Reputation: 1182

For either of the two solutions (@mortezaipo, @francisco-couzo) proposed so far, space efficiency could be improved via a custom startswith method to avoid constructing a new list in small_list[:len(start_list)]. For example:

def startswith(lst, start):
    for i in range(len(start)):
        if start[i] != lst[i]:
            return False
    return True

and then

[lst for lst in big_list if startswith(lst, start_list)]

(modeled after @mortezaipo's solution).

Upvotes: 0

mortymacs
mortymacs

Reputation: 3736

You can try it via an iterator, like so:

[x for x in big_list if x[:len(start_list)] == start_list]

Upvotes: 4

Francisco
Francisco

Reputation: 11476

Here's how I would write it:

def find_lists_starting_with(start, biglist):
    for small_list in biglist:
        if start == small_list[:len(start)]:
            yield small_list

This returns a generator instead, but you can call list to its result to get a list.

Upvotes: 1

Related Questions