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.
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]]
You should return 'the element has not been found' only after checking all the values, so you must remove the else, and push the second return outside of the for loops
Do not return in else. Program will return immediately after index 0, 0. Return fail value after both loops are done.
Find Element In Two-Dimensional Python Array - Stack Overflow
How to find a value in a 2D array in python? - Stack Overflow
How to find the row and column of element in 2d array in python? - Stack Overflow
searching a 2d array in python - best method + indentation error - Stack Overflow
This is an implementation without using numpy. It is not that efficient, but works fine.
rows = eval(input("How many rows in the list:"))
m = []
for row in range(rows):
value = eval(input("Enter a row:"))
m.append(value)
large = m[0][0]
x = 0
y = 0
for i in range(0, rows):
for j in range(0, len(m[i])):
if(large < m[i][j]):
large = m[i][j]
y = i
x = j
print(x, y, large)
This gives the (row,column) index of the max -
import numpy as np
m = np.array([[1,5,6],[2,6,7],[5,26,12]]) # input minified
print(m)
print np.unravel_index(m.argmax(), m.shape) # main code you need
You need to iterate over your main list and then you can use list.index() to find the sub-list index, for example:
def index_2d(data, search):
for i, e in enumerate(data):
try:
return i, e.index(search)
except ValueError:
pass
raise ValueError("{!r} is not in list".format(search))
And it will act exactly as list.index() but for a 2D array, so in your case:
position = index_2d(board, "18") # (4, 3)
print(board[position[0]][position[1]]) # 18
position = index_2d(board, "181") # ValueError: '181' is not in list
ind = np.where(np.array(board) == str(place1)) will return the indices of all elements in the board array equal to place. To replace those values do this: board[ind] = newval.
Basically,
import numpy as np
ind = np.where(np.array(board) == str(place1))
board[ind] = newval
l = [[98, 25, 33, 9, 41],
[67, 32, 67, 27, 85],
[38, 79, 52, 40, 58],
[84, 76, 44, 9, 2]]
def fnd(l,value):
for i,v in enumerate(l):
if value in v:
return {'row':i+1,'col':v.index(value)+1}
return {'row':-1,'col':-1}
print(fnd(l,40))
{'row': 3, 'col': 4}
If the number of columns will be constant as shown in the example, you can search using below code.
a = [[98, 25, 33, 9, 41],
[67, 32, 67, 27, 85],
[38, 79, 52, 40, 58],
[84, 76, 44, 9, 2]]
a_ind = [p[x] for p in a for x in range(len(p))] # Construct 1d array as index for a to search efficiently.
def find(x):
return a_ind.index(x) // 5 + 1, a_ind.index(x) % 5 + 1 # Here 5 is the number of columns
print(find(98), find(58), find(40))
#Output
(1, 1) (3, 5) (3, 4)
The main problem here is that break only exits the innermost loop. So, if an element is found, break will skip checking other elements in the same column, but still the outer loop will advance to next row. What you really want is either this:
found = False
for row in matrix:
for element in row:
if element == number:
found = True
break
if found:
break
if found:
print("Found")
else:
print("Not found")
(notice the other break) or, possibly, a more readable solution using a function:
def searchfor(matrix, number):
for row in matrix:
for element in row:
if element == number:
return True
return False
if searchfor(matrix, number):
print("Found")
else:
print("Not found")
Edit: It just occured to me that it is possible to write it without either a flag variable or a function, but it is not a particularly elegant way. Still, for completeness, here you are:
for row in matrix:
for element in row:
if element == number:
break
else:
continue
break
if element == number:
print("Found")
else:
print("Not found")
The continue statement will execute only if the inner loop was not exited by break, and it will advance the outer loop to the next row; otherwise the second break will end the outer loop.
You seem to be new to Python. In this language, code blocks are identified by the number of indents you have before an instruction. In your case, you have an if statement, but your else is not matching the indentation of that if statement.
You'd want your code to be something like this -
number=int(input("What number are you looking for?"))
flag = False
for i in range(rows):
for j in range(columns):
if matrix[i][j]==number:
print("Found it!")
flag = True
break
if flag == False:
print ("Not found!")
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?
First you need to access to your columns , so you can do that job with zip(*sudokuBoard) then for insert a value , you must check for existence the value in a proper row and column ! Note that you have your rows in sudokuColumn !
columns=map(list,zip(*sudokuBoard))
sudokuBoard=[[0 for sudokuRow in range(0,int(boardSize))] for sudokuColumn in range(0,int(boardSize))]
def insert_value(your_list,value,row,col):
if value not in columns[col] and value not in your_list[row]:
your_list[row][col]=value
else:
raise ValueError("you can not insert a duplicate value !!")
Try this:
def inBoard(value):
for row in sudokuBoard:
if value in row:
return True
return False
With this you can do something like this:
if inBoard(3):
print "already in board"
else:
print "well played"
>>> mylist = [[], ['shotgun', 'weapon'], ['pistol', 'weapon'], ['cheesecake', 'f
ood'], []]
>>> print mylist[2][1]
weapon
Remember a couple of things,
- don't name your list, list... it's a python reserved word
- lists start at index 0. so
mylist[0]would give[]
similarly,mylist[1][0]would give'shotgun' - consider alternate data structures like dictionaries.
Accessing through index works with any sequence (String, List, Tuple): -
>>> list1 = [[], ['shotgun', 'weapon'], ['pistol', 'weapon'], ['cheesecake', 'food'], []]
>>> list1[1]
['shotgun', 'weapon']
>>> print list1[1][1]
weapon
>>> print ' '.join(list1[1])
shotgun weapon
>>>
You can use join on the list, to get String out of list..
If you have
a=[[1,1],[2,1],[3,1]]
b=[[1,2],[2,2],[3,2]]
Then
a[1][1]
Will work fine. It points to the second column, second row just like you wanted.
I'm not sure what you did wrong.
To multiply the cells in the third column you can just do
c = [a[2][i] * b[2][i] for i in range(len(a[2]))]
Which will work for any number of rows.
Edit: The first number is the column, the second number is the row, with your current layout. They are both numbered from zero. If you want to switch the order you can do
a = zip(*a)
or you can create it that way:
a=[[1, 2, 3], [1, 1, 1]]
If you want do many calculation with 2d array, you should use NumPy array instead of nest list.
for your question, you can use:zip(*a) to transpose it:
In [55]: a=[[1,1],[2,1],[3,1]]
In [56]: zip(*a)
Out[56]: [(1, 2, 3), (1, 1, 1)]
In [57]: zip(*a)[0]
Out[57]: (1, 2, 3)
You need to iterate over all the indices of your list to see if an element is a value in one of the nested lists. You can simply iterate over the inner lists and check for the presence of your element, e.g.:
if not any(0 in x for x in board):
pass # the board is full
Using any() will serve as a short-stop whenever it encounters an element with a 0 in it so you don't need to iterate over the rest.
I will try to address what you did wrong:
if not 0 in board[0] or not 0 in board[1]: this is almost right - but you should use and because to be considered full, both boards must not have 0 at the same time.
Some options:
if not 0 in board[0] and not 0 in board[1]: # would work
if 0 not in board[0] and 0 not in board[1]: # more idiomatic
if not(0 in board[0] or 0 in board[1]): # put "not" in evidence, reverse logic
if not any(0 in b for b in board): # any number of boards