Inti
Inti

Reputation: 69

Filtering indexes of list

I have the following list of numbers:

List = [1, 2, 3, 4, 5, 6, 15]

I want the indexes of those numbers which are multiple of n, so I do:

def indexes(List, n):
      # to enumerate the numbers
      E = enumerate(List)
      # filtering tuples
      F = list(filter(lambda x:  x[1] % n == 0, E))
      return [ i[0] for i in F]

     indexes(List, 2)
     [1, 3, 5]

That's ok, but what happens when I add the variable m?

def Index( L, n, m):
      # enumeration
      E = enumerate(L)
      # filtering tuples
      F_n = list(filter(lambda x: x[1]%n == 0, E))
      F_m = list(filter(lambda x: x[1]%m == 0, E))
      L_n = [ l[0] for l in F_n]
      L_m = [ J[0] for J in F_m]
      return L_n + L_m

  >>>Index(List, 2, 5):
        [1, 3, 5]

Why that code doesn't returns [1, 3, 5, 4, 6]?

What is the mistake?

And how to create the function that returns that list?

Upvotes: 3

Views: 98

Answers (3)

Mihai Alexandru-Ionut
Mihai Alexandru-Ionut

Reputation: 48367

You can use a list comprehension in combination with enumerate method. Also, you can apply extended iterable unpacking operator in order to pass parameters as many you need.

List = [1, 2, 3, 4, 5, 6, 15]
def indexes(List, *vars):
   return [index for index, item in enumerate(List) for i in vars if item % i == 0 ]

print(indexes(List, 2, 5))

Output

[1, 3, 5, 4, 6]

Upvotes: 3

Kasravnd
Kasravnd

Reputation: 107287

A more general and Pythonic approach that works for any number of variables is to use an any() or all() function that check the Truth value of the condition for all the arguments. If you want the index to belongs to an item that is divisible buy all the arguments you need all() other wise you can use any() that returns True right after it encounters a match.

def indexes(lst, *args):
    return [i for i, j in enumerate(lst) if any(j % arg == 0 for arg in args)]

Demo:

>>> lst = [1, 2, 3, 4, 5, 6, 15, 99, 200, 13, 17, 400]

>>> indexes(lst, 99, 5, 2, 100)
[1, 3, 4, 5, 6, 7, 8, 11]
>>> 

And with all():

>>> indexes(lst, 5, 2, 100)
[8, 11]

Upvotes: 2

jpp
jpp

Reputation: 164683

The issue is enumerate returns an iterator from an iterable. Once it is exhausted, you may not use it again. Therefore, you can simply define a new enumerate iterator:

lst = [1, 2, 3, 4, 5, 6, 15]

def Index( L, n, m):

    # enumeration - notice we define 2 objects
    E, F = enumerate(L), enumerate(L)

    F_n = list(filter(lambda x: x[1]%n == 0, E))
    F_m = list(filter(lambda x: x[1]%m == 0, F))
    L_n = [ l[0] for l in F_n]
    L_m = [ J[0] for J in F_m]
    return L_n + L_m

res = Index(lst, 2, 5)

print(res)
[1, 3, 5, 4, 6]

Note there are better ways you can implement your algorithm.

Upvotes: 1

Related Questions