Try this:
def index_2d(myList, v):
for i, x in enumerate(myList):
if v in x:
return (i, x.index(v))
Usage:
>>> index_2d(myList, 3)
(1, 0)
Answer from Mark Byers on Stack OverflowPython: Return 2 ints for index in 2D lists given item - Stack Overflow
How to return the index of an element in a 2d array in python? - Stack Overflow
arrays - Search in 2D list using python to find x,y position - Stack Overflow
The fastest way to find indices of element in the 2D python list - Stack Overflow
Been messing around with numpy, trying to familiarize myself with it and seeing how I'd be able to utilize its arrays to store (very simple) map data for this text adventure game I've been working on. So far it seems like it'd be pretty darn useful, but I seem to have run into something of an issue.
My code is as follows (note: this is purposefully made with out a main class, because I am just trying to get the basic functionality down in my head before I incorporate it into my main program, and this is just easier for me):
# import numpy module as np
import numpy as np
# Establish the game map, a 3x3 grid of 0's
mainarray = np.array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
# Give feedback to make console easier to read
print(mainarray)
print("")
print("Placing player in center...")
# Place player on map (represented by a value of 1)
mainarray[1, 1] = 1
print(mainarray)
print("")
print("Locating player...")
# Attempt to find what the current index is of the value 1
print("")
print("Player is at index: ", np.where(mainarray == 1)[0][0])
In my head, I would like to eventually use this np.where() function (if I can) in one of the functions that moves my character. What I want to do is grab the current index of the "player" (represented by the number 1) and attempt to change that value to a 0, and change the value at an adjacent index to 1 (the tile that the player is moving to). Basically, I would like to use each index of the array as a sort of coordinate that I can take and use to move this "1" around the array, setting each index back to "0" after moving the "1", all based off user input.
Anyways, I am not getting any errors, however, the result that gets printed to the console is:
Player is at index: 1
Why is it just one number? It remains the same, even when I remove that second [0] in the last line. I don't fully understand how this function works, as this is the first time I've tried to use it, but since there are no errors, I have no clue what is going on.
Shouldn't I be receiving an index with two values, one for the column and one for the row? If not, how can I grab that as a result and use it in the way I described above? Is it even possible, or am I barking up the wrong tree with this function?
Try this:
def index_2d(myList, v):
for i, x in enumerate(myList):
if v in x:
return (i, x.index(v))
Usage:
>>> index_2d(myList, 3)
(1, 0)
If you are doing many lookups you could create a mapping.
>>> myList = [[1,2],[3,4],[5,6]]
>>> d = dict( (j,(x, y)) for x, i in enumerate(myList) for y, j in enumerate(i) )
>>> d
{1: (0, 0), 2: (0, 1), 3: (1, 0), 4: (1, 1), 5: (2, 0), 6: (2, 1)}
>>> d[3]
(1, 0)
You don't need to define no_classes yourself. Use enumerate():
def in_list(c, classes):
for i, sublist in enumerate(classes):
if c in sublist:
return i
return -1
Use list.index(item)
a = [[1,2],[3,4,5]]
def in_list(item,L):
for i in L:
if item in i:
return L.index(i)
return -1
print in_list(3,a)
# prints 1
You can create a temporary mapping from the list2 and use it afterwards to create your output:
list1 = [[0, 1], [2, 3], [4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14]]
list2 = [[8, 2], [1, 9], [6, 4], [13, 5, 0], [14, 7, 10], [12, 11, 3]]
m = {v: i for i, t in enumerate(list2) for v in t}
out = [[m[list1[i][j]] for j in range(len(t))] for i, t in enumerate(list2)]
print(out)
Prints:
[[3, 1], [0, 5], [2, 3], [2, 4, 0], [1, 4, 5], [5, 3, 4]]
Use a mapping dictionary for the indices of the sublists in list2, then a list comprehension:
mapper = {x: i for i, l in enumerate(list2) for x in l}
list3 = [[mapper.get(x, -1) for x in l] for l in list1]
NB. I assigned -1 to the potentially missing values. Also if you have duplicates in list2 the last index will be used.
Output: [[3, 1], [0, 5], [2, 3], [2, 4, 0], [1, 4, 5], [5, 3, 4]]
You can use np.where to return a tuple of arrays of x and y indices where a given condition holds in an array.
If a is the name of your array:
>>> np.where(a == 1)
(array([0, 0, 1, 1]), array([0, 1, 2, 3]))
If you want a list of (x, y) pairs, you could zip the two arrays:
>>> list(zip(*np.where(a == 1)))
[(0, 0), (0, 1), (1, 2), (1, 3)]
Or, even better, @jme points out that np.asarray(x).T can be a more efficient way to generate the pairs.
Using numpy, argwhere may be the best solution:
import numpy as np
array = np.array([[1, 1, 0, 0],
[0, 0, 1, 1],
[0, 0, 0, 0]])
solutions = np.argwhere(array == 1)
print(solutions)
>>>
[[0 0]
[0 1]
[1 2]
[1 3]]
Assuming you don't want to reinvent the wheel I believe this question has the answer you're looking for: Is there a Numpy function to return the first index of something in an array?
import numpy as np
a = np.array([[1,2,4],[4,5,6]])
item = 4
row_indices, col_indices = np.where(a == item)
Try something like this.
>>> l = [[1,2,3],[4,5],[6,7,8,9]]
>>> x = 1
>>> y = 2
>>> v = l[x][y] if len(l) > x and len(l[x]) > y else None
>>> v is None
True
I don't know of an automatic way to do it, but if
a = [[1,2],[3,4],[5,6]]
and you want to find the location of 3, you can do:
x = [x for x in a if 3 in x][0]
print 'The index is (%d,%d)'%(a.index(x),x.index(3))
The output is:
The index is (1,0)
For two dimensional list; you can iterate over rows and using .index function for looking for item:
def find(l, elem):
for row, i in enumerate(l):
try:
column = i.index(elem)
except ValueError:
continue
return row, column
return -1
tl = [[1,2,3],[4,5,6],[7,8,9]]
print(find(tl, 6)) # (1,2)
print(find(tl, 1)) # (0,0)
print(find(tl, 9)) # (2,2)
print(find(tl, 12)) # -1
You don't want a 2D list, you want a dictionary, and luckily, it's super simple to go from a 2D list (where each sublist has only two elements) to a dictionary:
prices = [['Bread',5],['Loaf',100],['Meat_Chicken',2.4],['Meat_Cow',450]]
d = dict(prices)
# {'Bread': 5, 'Loaf': 100, 'Meat_Chicken': 2.4, 'Meat_Cow': 450}
Now all you have to do is query the dictionary (O(1) lookup):
>>> d['Bread']
5
If you want to enable error checking:
>>> d.get('Bread', 'Item not found')
5
>>> d.get('Toast', 'Item not found')
'Item not found'
You can easily go from your "2d-list" from those two separate sequences by using zip
super_market_prices=[['Bread',5],['Loaf',100],['Meat_Chicken',2.4],['Meat_Cow',450]]
l1, l2 = zip(*super_market_prices)
>>> print(l1)
('Bread', 'Loaf', 'Meat_Chicken', 'Meat_Cow')
>>> print(l2)
(5, 100, 2.4, 450)
and just keep your code as is.
Loop through your list and search each sublist for the string.
Testlist = [
["Romeo and Juliet","Shakespeare"],
["Othello","Play"],
["Macbeth","Tragedy"]
]
Value = "Tragedy"
for index, lst in enumerate(Testlist):
if Value in lst:
print( index, lst.index(Value) )
You can also use the map operator:
# Get a boolean array - true if sublist contained the lookup value
value_in_sublist = map(lambda x: value in x, test_list)
# Get the index of the first True
print(value_in_sublist.index(True))