Finding coordinate of maximum value in list of lists - python

I am tasked with finding the exact coordinate of a maximum value in a list of lists in python. This list of lists is referred to as a grid to emulate topographical coordinates.
Here is the grid, along with my code to find the maximum:
grid = [[15, 16, 18, 19, 12, 11],
[13, 19, 23, 21, 16, 12],
[12, 15, 17, 19, 22, 10],
[10, 14, 16, 13, 9, 6]]
maxi = 0
for i in grid:
for j in i:
if j > maxi:
maxi = j
This code finds the maximum, however I am stuck on finding the coordinates. The output should be:
global max: (1,2) 23
Because the maximum (23) is on the First row, and on the second column.
I have tried using index and find but they do not work or take my value as an input. Any tips or help are appreciated, thank you in advance.

You can use the builtin function enumerate.
Update your code to this:
grid = [[15, 16, 18, 19, 12, 11],
[13, 19, 23, 21, 16, 12],
[12, 15, 17, 19, 22, 10],
[10, 14, 16, 13, 9, 6]]
maxi = -float('inf')
maxCoord = None
for i, row in enumerate(grid):
for j, col in enumerate(row):
if col > maxi:
maxi = col
maxCoord = (i, j)
print(maxCoord, maxi) #(1, 2) 23

Enumerate could be an option, as it was already proposed. If you want to keep your original function to find the max value, you can call its coordinates using:
for sublist in grid:
if maxi in sublist:
print(grid.index(sublist), sublist.index(maxi))

Related

Add new element in the next sublist depending in if it has been added or not (involves also a dictionary problem) python

Community of Stackoverflow:
I'm trying to create a list of sublists with a loop based on a random sampling of values of another list; and each sublist has the restriction of not having a duplicate or a value that has already been added to a prior sublist.
Let's say (example) I have a main list:
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
#I get:
[[1,13],[4,1],[8,13]]
#I WANT:
[[1,13],[4,9],[8,14]] #(no duplicates when checking previous sublists)
The real code that I thought it would work is the following (as a draft):
matrixvals=list(matrix.index.values) #list where values are obtained
lists=[[]for e in range(0,3)] #list of sublists that I want to feed
vls=[] #stores the values that have been added to prevent adding them again
for e in lists: #initiate main loop
for i in range(0,5): #each sublist will contain 5 different random samples
x=random.sample(matrixvals,1) #it doesn't matter if the samples are 1 or 2
if any(x) not in vls: #if the sample isn't in the evaluation list
vls.extend(x)
e.append(x)
else: #if it IS, then do a sample but without those already added values (line below)
x=random.sample([matrixvals[:].remove(x) for x in vls],1)
vls.extend(x)
e.append(x)
print(lists)
print(vls)
It didn't work as I get the following:
[[[25], [16], [15], [31], [17]], [[4], [2], [13], [42], [13]], [[11], [7], [13], [17], [25]]]
[25, 16, 15, 31, 17, 4, 2, 13, 42, 13, 11, 7, 13, 17, 25]
As you can see, number 13 is repeated 3 times, and I don't understand why
I would want:
[[[25], [16], [15], [31], [17]], [[4], [2], [13], [42], [70]], [[11], [7], [100], [18], [27]]]
[25, 16, 15, 31, 17, 4, 2, 13, 42, 70, 11, 7, 100, 18, 27] #no dups
In addition, is there a way to convert the sample.random results as values instead of lists? (to obtain):
[[25,16,15,31,17]], [4, 2, 13, 42,70], [11, 7, 100, 18, 27]]
Also, the final result in reality isn't a list of sublists, actually is a dictionary (the code above is a draft attempt to solve the dict problem), is there a way to obtain that previous method in a dict? With my present code I got the next results:
{'1stkey': {'1stsubkey': {'list1': [41,
40,
22,
28,
26,
14,
41,
15,
40,
33],
'list2': [41, 40, 22, 28, 26, 14, 41, 15, 40, 33],
'list3': [41, 40, 22, 28, 26, 14, 41, 15, 40, 33]},
'2ndsubkey': {'list1': [21,
7,
31,
12,
8,
22,
27,...}
Instead of that result, I would want the following:
{'1stkey': {'1stsubkey': {'list1': [41,40,22],
'list2': [28, 26, 14],
'list3': [41, 15, 40, 33]},
'2ndsubkey': {'list1': [21,7,31],
'list2':[12,8,22],
'list3':[27...,...}#and so on
Is there a way to solve both list and dict problem? Any help will be very appreciated; I can made some progress even only with the list problem
Thanks to all
I realize you may be more interested in finding out why your particular approach isn't working. However, if I've understood your desired behavior, I may be able to offer an alternative solution. After posting my answer, I will take a look at your attempt.
random.sample lets you sample k number of items from a population (collection, list, whatever.) If there are no repeated elements in the collection, then you're guaranteed to have no repeats in your random sample:
from random import sample
pool = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
num_samples = 4
print(sample(pool, k=num_samples))
Possible output:
[9, 11, 8, 7]
>>>
It doesn't matter how many times you run this snippet, you will never have repeated elements in your random sample. This is because random.sample doesn't generate random objects, it just randomly picks items which already exist in a collection. This is the same approach you would take when drawing random cards from a deck of cards, or drawing lottery numbers, for example.
In your case, pool is the pool of possible unique numbers to choose your sample from. Your desired output seems to be a list of three lists, where each sublist has two samples in it. Rather than calling random.sample three times, once for each sublist, we should call it once with k=num_sublists * num_samples_per_sublist:
from random import sample
pool = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
num_sublists = 3
samples_per_sublist = 2
num_samples = num_sublists * samples_per_sublist
assert num_samples <= len(pool)
print(sample(pool, k=num_samples))
Possible output:
[14, 10, 1, 8, 6, 3]
>>>
OK, so we have six samples rather than four. No sublists yet. Now you can simply chop this list of six samples up into three sublists of two samples each:
from random import sample
pool = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
num_sublists = 3
samples_per_sublist = 2
num_samples = num_sublists * samples_per_sublist
assert num_samples <= len(pool)
def pairwise(iterable):
yield from zip(*[iter(iterable)]*samples_per_sublist)
print(list(pairwise(sample(pool, num_samples))))
Possible output:
[(4, 11), (12, 13), (8, 15)]
>>>
Or if you really want sublists, rather than tuples:
def pairwise(iterable):
yield from map(list, zip(*[iter(iterable)]*samples_per_sublist))
EDIT - just realized that you don't actually want a list of lists, but a dictionary. Something more like this? Sorry I'm obsessed with generators, and this isn't really easy to read:
keys = ["1stkey"]
subkeys = ["1stsubkey", "2ndsubkey"]
num_lists_per_subkey = 3
num_samples_per_list = 5
num_samples = num_lists_per_subkey * num_samples_per_list
min_sample = 1
max_sample = 50
pool = list(range(min_sample, max_sample + 1))
def generate_items():
def generate_sub_items():
from random import sample
samples = sample(pool, k=num_samples)
def generate_sub_sub_items():
def chunkwise(iterable, n=num_samples_per_list):
yield from map(list, zip(*[iter(iterable)]*n))
for list_num, chunk in enumerate(chunkwise(samples), start=1):
key = f"list{list_num}"
yield key, chunk
for subkey in subkeys:
yield subkey, dict(generate_sub_sub_items())
for key in keys:
yield key, dict(generate_sub_items())
print(dict(generate_items()))
Possible output:
{'1stkey': {'1stsubkey': {'list1': [43, 20, 4, 27, 2], 'list2': [49, 44, 18, 8, 37], 'list3': [19, 40, 9, 17, 6]}, '2ndsubkey': {'list1': [43, 20, 4, 27, 2], 'list2': [49, 44, 18, 8, 37], 'list3': [19, 40, 9, 17, 6]}}}
>>>

Given two lists, return the minimal number of changes needed for one list to become the other

Given two lists with the same length:
a = [15, 10, 15, 14]
b = [14, 15, 14, 14]
What is the minimal number of changes needed for 'a' to become 'b'?
This is my attempt at it:
c3=0
fht2= [15, 10, 15, 14]
sht2= [14, 15, 14, 14]
for i in range(0,len(fht2)):
for j in range(0,len(sht2)):
if fht2==sht2:
c=0
else:
if fht2!=sht2:
if fht2[i]!=sht2[j] and fht2[i]<=sht2[j]:
fht2[i]+=abs(fht2[i]-sht2[j])
c3+=1
if fht2[i]!=sht2[j] and fht2[i]>=sht2[j]:
fht2[i]-=abs(fht2[i]-sht2[j])
c3+=1
print(fht2)
print(c3)
The output should be:
[14, 15, 14, 14]
3
However, my output is :
[14, 14, 14, 14]
11
Please assist.
a = [15, 10, 15, 14]
b = [14, 15, 14, 14]
list_length = len(a)
print("list length:",list_length)
counter = 0
for i in range(list_length):
if a[i]!= b[i]:
counter = counter + 1
print ("minimal number of changes is:",counter)
Output:
list length:4
minimal number of changes is: 3
Please learn to write a better question

How can I find the longest contiguous subsequence in a rising sequence in Python?

I need to find the longest contiguous subsequence in a rising sequence in Python.
For example if I have A = [1, 2, 3, 5, 8, 9, 11, 13, 17, 18, 19, 20, 21, 25, 27, 28, 29, 30]
The answer would be [17, 18, 19, 20, 21] because it's the longest contiguous subsequence with 5 numbers (whereas [1, 2, 3] is 3 numbers long and [27, 28, 29, 30] is 4 numbers long.)
My code is stuck in an endless loop
num_list = [1, 2, 3, 5, 8, 9, 11, 13, 17, 18, 19, 20, 21, 23, 25, 26, 27]
longest_sequence = {}
longest_sequence_length = 1
for num in num_list:
sequence_length = 1
while True:
if (num + sequence_length) in num_list:
sequence_length += 1
else:
if sequence_length > longest_sequence_length:
longest_sequence_length_length = sequence_length
longest_sequence = {"start": num, "end": num + (sequence_length - 1)}
break
print(f"The longest sequence is {longest_sequence_length} numbers long"
f" and it's between {longest_sequence['start']} and {longest_sequence['end']}")
You can use numpy to solve it in one line:
import numpy as np
A = [1, 2, 3, 5, 8, 9, 11, 13, 17, 18, 19, 20, 21, 25, 27, 28, 29, 30]
out = max(np.split(A, np.where(np.diff(A) != 1)[0] + 1), key=len).tolist()
You can also find the same outcome by running 3 iterations.
(i) First you need to find the differences between consecutive elements in A; that's found in diff (with zip(A,A[1:]), you can access consecutive elements).
(ii) Then you split A on indices where the difference is not 1; that's being done in the second iteration. Basically, if a difference is 1, append the value in A to the running sublist, if not, create a new sublist and put the corresponding value to this new sublist.
(iii) Finally, using max() function, you can find the longest sublist using key=len.
This exact same job is done by the numpy code above.
diff = [j-i for i,j in zip(A, A[1:])]
splits = [[A[0]]]
for x,d in zip(A[1:], diff):
if d == 1:
splits[-1].append(x)
else:
splits.append([x])
out = max(splits, key=len)
Output:
[17, 18, 19, 20, 21]
In line 13 you need a break instead of a continue statement.
Also, in line 11 you had a little mistake, added an extra "_length" to you variable name.

Find indices of line intersection in shapely

I would like to find a better solution for what I am proposing below. I am trying to find the indices associated with a line intersection when using the shapely library. Solutions from other libraries are welcome.
Right now I am iterating through the location coordinates and storing the index where an intersection is observed. I would like to do away with the loop and create a more streamlined function.
The code below results in a single intersection/crossing.
line_crossings = []
latitude = [10, 11, 12, 13, 14, 15, 16, 17 ,18]
longitude = [7, 9, 11, 13, 17, 19, 23, 25 ,29]
location = np.column_stack((latitude, longitude))
C = (14.5, 14.5)
D = (12.3, 12.5)
line2 = LineString([C, D])
for idx in range(0, len(location)-1):
A = (latitude[idx], longitude[idx])
B = (latitude[idx+1], longitude[idx+1])
line1 = LineString([A, B])
int_pt = line2.intersection(line1)
if int_pt.type == 'Point':
print(int_pt)
line_crossings.append(idx)
Update
It would seem the quickest way to get the coordinates of the crossings is as follows:
latitude = [10, 11, 12, 13, 14, 15, 16, 17 ,16, 15, 14, 13, 12, 11, 10]
longitude = [7, 9, 11, 13, 17, 19, 23, 25 ,29, 25, 23, 13, 13, 13, 11]
location = LineString([i for i in zip(latitude,longitude)])
C = (14.5, 14.5)
D = (12.3, 12.5)
gate = LineString([C, D])
[[i.x, i.y] for i in location.intersection(gate)]
But I need to be able to get the index in the location variable where the intersection occurs. Is it possible to get this using the list comprehension?

What is the easiest way in NumPy to index vectors of a matrix excluding one index in each row? [duplicate]

This question already has answers here:
How do I get all the values from a NumPy array excluding a certain index?
(5 answers)
Closed 4 years ago.
Suppose I have a NumPy ndarray M with the following content at M[0,:]:
[2, 3.9, 7, 9, 0, 1, 8.1, 3.2]
and I am given an integer, k, at runtime between 0 and 7. I want to produce the vector consisting of all items in this row except at column k. (Example: if k=3, then the desired vector is [2,3.9,7,0,1,8.1,3.2])
Is there an easy way to do this?
What if I have a vector of indices k, one for each row of M, representing the column I want to exclude from the row?
I'm kind of lost, other than a non-vectorized loop that mutates a result matrix:
nrows = M.shape[0]
result = np.zeros(nrows,M.shape[1]-1))
for irow in xrange(nrows):
result[irow,:k[irow]] = M[irow,:k[irow]] # content before the split point
result[irow,k[irow]:] = M[irow,k[irow]+1:] # content after the split point
One approach would be with masking/boolean-indexing -
mask = np.ones(M.shape,dtype=bool)
mask[np.arange(len(k)),k] = 0
out = M[mask].reshape(len(M),-1)
Alternativley, we could use broadcasting to get that mask -
np.not_equal.outer(k,np.arange(M.shape[1]))
# or k[:,None]!=np.arange(M.shape[1])
Thus, giving us a one-liner/compact version -
out = M[k[:,None]!=np.arange(M.shape[1])].reshape(len(M),-1)
To exclude multiple ones per row, edit the advanced-indexing part for the first method -
def exclude_multiple(M,*klist):
k = np.stack(klist).T
mask = np.ones(M.shape,dtype=bool)
mask[np.arange(len(k))[:,None],k] = 0
out = M[mask].reshape(len(M),-1)
return out
Sample run -
In [185]: M = np.arange(40).reshape(4,10)
In [186]: exclude_multiple(M,[1,3,2,0],[4,5,8,1])
Out[186]:
array([[ 0, 2, 3, 5, 6, 7, 8, 9],
[10, 11, 12, 14, 16, 17, 18, 19],
[20, 21, 23, 24, 25, 26, 27, 29],
[32, 33, 34, 35, 36, 37, 38, 39]])
Improvement on #Divakar's answer to extend this to zero or more excluded indices per row:
def excluding(A, *klist):
"""
excludes column k from each row of A, for each k in klist
(make sure the index vectors have no common elements)
"""
mask = np.ones(A.shape,dtype=bool)
for k in klist:
mask[np.arange(len(k)),k] = 0
return A[mask].reshape(len(A),-1)
Test:
M = np.arange(40).reshape(4,10)
excluding(M,[1,3,2,0],[4,5,8,1])
returns
array([[ 0, 2, 3, 5, 6, 7, 8, 9],
[10, 11, 12, 14, 16, 17, 18, 19],
[20, 21, 23, 24, 25, 26, 27, 29],
[32, 33, 34, 35, 36, 37, 38, 39]])

Categories

Resources