Welcome, guest | Sign In | My Account | Store | Cart

This algorithm searches for more than one element in a list. The input is a list that you want to search through and a list of elements that you want to search for. The output is a multidimensional list with the positions of the elements you are searching for in the search list in the order that you listed them.

Python, 1 line
1
find = lambda searchList, elem: [[i for i, x in enumerate(searchList) if x == e] for e in elem]

I would like to acknowledge especially Andrey Telnov for rewriting the loop and introducing me into 1 line for loops and I would like to acknowledge Seung-jin Kim for introducing me to the lambda function and helping to make my primeList algorithm only one line.

Example:

find([1,4,1,4,6,5,5,5,4,2,3],[1,3,5])

Returns: [[0, 2], [10], [5, 6, 7]]

1 comment

Scott S-Allen 8 years, 10 months ago  # | flag

Depending upon your use-case(s), collections.defaultdict (think 'keyed' lists for each set of indexes) can offer some utility for this kind of application. As well, filter or itertools.ifilter can be used. Finally, the comprehension you are using is a staple but is also available as:

blah = (i for i in thing)

At first blush it doesn't seem much different than the square-brackets. Check out the docs for the nuances (as with filter :: ifilter too).

Tradeoff's with the modules I note above are insignificant with small iterations (10k iterations with fractions of seconds difference) but long-term readability, and extra functionality, can be a benefit.

While "slower" than the recipe, here's a starting point to play with if you like:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""\
A practical example using collections' defaultdict

Response to http://code.activestate.com/recipes/577943/ (r1)

Released to public domain for those that fear people hunting them down
like rrrabbits'z. While potentially tasty, its not s'porting. SSA-2013-01-26

"""
from collections import defaultdict


def ddict_examp(src, msk=None):
    """\
    Example using defaultdict to group value indexes with optional mask

    """
    ddl = defaultdict(list)

    for idx, val in enumerate(src):
        if msk is not None and val not in msk:
            continue

        ddl[val].append(idx)

    return ddl

def test():
    """\
    Test example

    >>> SRC = [1,4,1,4,6,5,5,5,4,2,3]
    >>> MSK = [1,3,5]

    >>> tmp = ddict_examp(SRC)
    >>> tmp[5]
    [5, 6, 7]

    # entire indexed source within the defaultdict, therefore all keys/values
    >>> tmp.keys()
    [1, 2, 3, 4, 5, 6]

    # long-way to match recipe results as separatate step
    >>> [tmp[i] for i in MSK]
    [[0, 2], [10], [5, 6, 7]]

    # short-way to match recipe results using optional mask
    >>> tmp = ddict_examp(SRC, MSK)
    >>> tmp.values()
    [[0, 2], [10], [5, 6, 7]]

    # should look more familiar than the native repr
    >>> dict(tmp)
    {1: [0, 2], 3: [10], 5: [5, 6, 7]}

    """
    pass

if __name__ == '__main__':

    import doctest
    doctest.testmod()

Hopefully this will help someone along the way.