2

I am trying to search a 2D array of characters and return the array indices, (x_T,y_T), of all of the letter T's in the array. I figure this could easily done with two stacked for loops but I was curious to know if it could be done my efficiently using list comprehension. I have tried things like:

TPos = [[x, y] for x in range(0, len(array[x])) for y in range(0, len(array[x][y])) if array[x][y] == 'T']

But I am getting errors to do with array bounds. Could someone point me in the right direction. Cheers, Jack

Edit

Now trying to use 'ndenumerate' like so:

TPos = [pos for pos, x in numpy.ndenumerate(array) if x == "T"]
0

4 Answers 4

4

This ended up being a beast to one-line, for readability it may be easier to break it up.

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

reduce(lambda x,y: x+y, [[(x,y) for y in range(len(l[y])) if l[x][y] == 'T'] for x in range(len(l))])

Output

[(0, 2), (1, 0), (1, 1), (2, 1), (2, 2)]

Edit With numpy this is much simpler.

import numpy as np
[pos for pos, x in np.ndenumerate(np.array(l)) if x == 'T']

Output

[(0, 2), (1, 0), (1, 1), (2, 1), (2, 2)]
Sign up to request clarification or add additional context in comments.

6 Comments

Cheers Cyber, cool answer. Any idea why: TPos = [pos for pos, x in numpy.ndenumerate(array) if x == "T"] doesnt work?
I didn't even know about numpy.ndenumerate, that is much simpler!
yeah its great! Cant't get it to work though. Returns empty array
I just tried it with my sample array l from above, it worked just as expected.
Ah yeah I was being daft. ndeumerate wtf
|
1

numpy where does this simply:

In [16]: l = [['a','b','T'],
   ....:      ['T','T','g'],
   ....:      ['c','T','T']]

In [20]: np.where(np.array(l)=='T')
Out[20]: (array([0, 1, 1, 2, 2]), array([2, 0, 1, 1, 2]))

In [22]: zip(*np.where(np.array(l)=='T'))
Out[22]: [(0, 2), (1, 0), (1, 1), (2, 1), (2, 2)]

Without numpy here's my version of the list comprehension:

In [27]: [(i,j) for i,v in enumerate(l) for j,k in enumerate(v) if k=='T']
Out[27]: [(0, 2), (1, 0), (1, 1), (2, 1), (2, 2)]

1 Comment

nice inversion of the iteration to go straight to the list of tuples -- thanks -- I learned something!
0

a=[[1,2,3,4],[5,6,7,8]]

def return_indexes(some_list,what_you_want_to_find):
    temp=[]
    for i in range(len(some_list)):
        for j in range(len(a[i])):
            if a[i][j] == what_you_want_to_find:
                temp.append([i,j])
    return temp

print return_indexes(a,7)

3 Comments

This is a viable function, but the question is asking specifically for list comprehensions.
This function is not correct. It will return only the first match, not all matches.
I didn't see Cyber's awesome answer until after my post.
0

Not quite as nice as @Cyber's answer (i.e., list of tuple lists rather than list of tuples), but uses "vanilla" list comprehensions with enumerate (hey, I got curious):

l = [['a','b','T'],['T','T','g'],['c','T','T']]
[[(i,j) for j,col in enumerate(row) if col=='T'] for i,row in enumerate(l)]

Output

[[(0, 2)], [(1, 0), (1, 1)], [(2, 1), (2, 2)]]

of course you could apply reduce(lambda ...) or similar approach to this to get a list of tuples.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.