3

I have a list:

['a','b','b','c']

to find all occurrences of an element I use:

incd=['a','b','b','c']
indeces=[i for i, x in enumerate(incd) if x == 'b']

how can I search for two elements and all their positions?

w1='a'
w2='b'
indeces=[i for i, x in enumerate(incd) if x == w1|w2]

returns

TypeError: unsupported operand type(s) for |: 'str' and 'str'

and

indeces=[i for i, x in enumerate(incd) if x == 'a|b']

returns

[]

both fails

I would like to have returned

[0, 1, 2]
  • Why is pandas tagged in here? – DirtyBit Apr 18 at 15:33
2

you do that: you have to use the condition 'or'

incd = ['a', 'b', 'b', 'c']
w1 = 'a'
w2 = 'b'
indeces = [i for i, x in enumerate(incd) if x == w1 or x== w2]

if you have lot of data to test: use a list

w = ['a', 'b' ,'d',...]
indeces = [i for i, x in enumerate(incd) if x in w]
  • what if I go up to w7? It will be a long statement – alex Apr 18 at 18:32
  • in this case you work with a list – Frenchy Apr 18 at 18:38
4

IIUC,

s=pd.Series(incd)
s[s.eq(w1)|s.eq(w2)].index
#Int64Index([0, 1, 2], dtype='int64')
  • succinct :) love it – Chris A Apr 18 at 16:28
  • @ChrisA thanks much. :) – anky_91 Apr 18 at 17:05
2

Since you tag pandas

l=['a','b','b','c']

s=pd.Series(range(len(l)),index=l)
s.get(['a','b'])
Out[893]: 
a    0
b    1
b    2
dtype: int64
2

I suggest going through the Operators in Python.

Replace this:

if x == w1|w2   

With this:

if x == w1 or x == w2

enumerate over the list, and check if the element is equal to w1 or w2:

s = ['a','b','b','c']

w1 = 'a'
w2 = 'b'

for indx, elem in enumerate(s):
   if elem == w1 or elem == w2:
      print("Elem: {} at Index {}".format(elem, indx))

OUTPUT:

Elem: a at Index 0
Elem: b at Index 1
Elem: b at Index 2

Shorter-version:

print([i for i, e in enumerate(s) if e == w1 or e == w2])   # to have a tuple of both elem and indx replace i with (e,i)

OUTPUT:

[0, 1, 2]
  • 1
    love the explanation – alex Apr 18 at 15:35
  • @alex Thank you! Happy coding! :) – DirtyBit Apr 18 at 15:52
1

Using a set for more speed and a dynamic number of elements to search for:

find = {2, 3} # The elements we want to find
a = [1,2,2,3,4] # our list
x = [ind for ind, val in enumerate(a) if val in find]
print(x)
1

You can use in operator to expression logical OR relation.

incd = list('abcd')
w1, w2 = 'a', 'b'

indeces = [i for i, x in enumerate(incd) if x in [w1, w2]]

It results correct indeces as desired

indeces = [0, 1]
0
indeces=[i for i, x in enumerate(incd) if x == w1 or x == w2]

  • 1
    Hi, please add some explanation to why this is a solution. Thanks – d_kennetz Apr 18 at 16:58
0

Use a defaultdict with list as its default

from collections import defaultdict
d = defaultdict(list)
for n,e in enumerate(incd): 
    d[e].append(n)

What's in d at this point?

>>> d
defaultdict(<class 'list'>, {'a': [0], 'b': [1, 2], 'c': [3]})

and to get positions of 'a' or 'b' (and prove it works for a key 'foo' not in incd)

print( d['a']+d['b']+d['foo'] )
# gives [0,1,2]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.