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"]
JMzance
  • 1,704
  • 4
  • 30
  • 49

4 Answers4

3

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)]
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
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)]
hpaulj
  • 221,503
  • 14
  • 230
  • 353
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)

Sarah
  • 11
  • 2
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.

Community
  • 1
  • 1
jstevenco
  • 2,913
  • 2
  • 25
  • 36