Reputation: 4276
I have a 2D list that has either True or False in it (although I'm also interested in non-boolean values). I want to know the first True value that appears in this list as a tuple.
For example [[False, False], [True, False]]
returns (1, 0)
.
This is the non-pythonic code I have
for x in range(0, width):
for y in range(0, height):
if allFood[x][y]:
return (x, y)
Upvotes: 0
Views: 53
Reputation: 77424
While there is no need to necessarily use NumPy for this, it is nonethless a very good choice, especially if this indicates broader use of multidimensional arrays in your application.
In [14]: map(tuple, np.argwhere([[False, False], [True, False]]))[0]
Out[14]: (1, 0)
Upvotes: 1
Reputation: 2130
Use list comprehensions:
def f():
mat = [[False, False], [True, False]]
return [(ind1, ind2) for ind1, sublist in enumerate(mat) for ind2, elem in
enumerate(sublist) if elem is True][0]
Upvotes: 0
Reputation: 42411
I would keep your current code as it is. But if you're looking for something with list comprehensions, generators, and so forth, you can create a generator (g
) that basically does the same thing as your current code and then return the first value from it. For example:
# Example data.
xs = [[0,0,1,1], [1,0], [0,1,0]]
g = ((i, j) for i, ys in enumerate(xs) for j, y in enumerate(ys) if y)
return next(g, None) # (0, 2)
Upvotes: 1
Reputation: 246
I think this function should work for nested lists of any size.
def ret_tup(lst):
#Get the index of the first nested list which has a true value.
truthidx =([any(value) for value in lst]).index(True)
#Return the tuple as 0 and 1
return tuple({True:1,False:0}[value] for value in lst[truthidx])
##Examples
a =[[False,False],[False,False],[True,True]]
print (ret_tup(a)) #Returns (1,1)
b = [[False,False,False],[False,False,False],[False,False], [True,False,True,False]]
print(ret_tup(b)) #Returns (1,0,1,0)
Upvotes: 0
Reputation: 30210
Your code is probably most directly mapped to a method using itertools.product
import itertools
def func(<...>):
for (x,y) in itertools.product(xrange(width), xrange(height)):
if allFood[x][y]: return (x,y)
But I'm not sure it's necessary, it increases the complexity (if you don't know about itertools), and increases the character count.
Upvotes: 0
Reputation: 174696
Seems like you want something like this,
>>> l = [[False, False], [True, False]]
>>> [1 if j is True else 0 for i in l for j in i if True in i]
[1, 0]
>>> [1 if j else 0 for i in l for j in i if True in i]
[1, 0]
Upvotes: 0