Finding points in a 2d array - python

I've started coding recently and my preferred language is python. I've come across a problem I'm having trouble with.
The problem is finding the index in a 2d array where the number is either larger than the numbers to the left and right and smaller than the numbers above and below or vice versa.
I know a 2d array can be defined as list = [[1, 2], [3, 4], [5, 6]] but as for working out the algorithm to sort the problem is at the present time beyond me. Could someone please offer a solution?

min(enumerate(list[0]),key=lambda x:x[1]) will find the (index,value) pair with the smallest value from list[0] ((0,1) in this example). max(enumerate(list[0]),key=lambda x:x[1]) will find the largest.
Note (since you said you're new) this is the same as:
def first_index(L):
return l[1]
min(enumerate(list[0]),key=first_index)
new_list=[L[0] for L in list] will make a list containing the 0th element from each list ([1,3,5] in this example). You'll probably want to do this for each column using for index in range(len(list[0]):
Note (since you're new) this is the same as:
new_list=list()
for L in list:
new_list.append(L[0])

Related

What is wrong with my function to get all subsets of a list?

def getAllSubsets(lst):
"""
lst: A list
Returns the powerset of lst, i.e. a list of all the possible subsets of lst
"""
if not lst:
return []
withFirst = [[lst[0]] + rest for rest in getAllSubsets(lst[1:])]
withoutFirst = getAllSubsets(lst[1:])
return withFirst + withoutFirst
I don't fully understand how it is managing to getAllSubsets of given list. This function was provided to me, not written by me. An explanation of how it works would be appreciated.
Karl has already pointed out the error in the original code, and I think explanations have been offered for how the recursion works, but we can also make the code shorter in the following way:
def powersetlist(s):
r = [[]]
for e in s:
r+=[x+[e] for x in r]
return r
Here, we update what is in r at every element e in our list s, and then add the new subsets with e to our existing r. I think we avoid recursion in this case.
Output for [1,2,3,4]:
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3],
[1, 2, 3], [4], [1, 4], [2, 4], [1, 2, 4],
[3, 4], [1, 3, 4], [2, 3, 4], [1, 2, 3, 4]]
Your question title and question body are contradictory, as the former makes it sound like there's a problem with the program and you're trying to figure out what it is. The problem with the program is that the line return [] is returning an empty list, when instead it should be returning a list containing an empty list. As for the body of the question, that is asking for an explanation for how the program is supposed to work:
The basic idea of the program that given an original set A and subset B, it is the case that for every element of A, it either is or isn't in B. That is, B can be constructed by going through each element of A, and for that element, making a decision as to whether to include it or not. This then suggests a recursive algorithm for creating subsets: given a set A, consider the "tail" of A. By that I mean, all the elements of A other than the "first" one (sets don't really have a first element, but the input to this function is actually a list, rather than a set, so there is a first element). Find all the subsets for the tail of A, then, for each subset that you find that way, create two subsets: one that includes the first element of A, and another that doesn't.
So how the algorithm works is that it sets the first element of the input aside, then calls the function on the remaining elements, get all the resulting subsets, and for each of them creates two subsets, one with and one without the element that was set aside. Of course, if you keep removing the first element, you'll eventually get an empty list. So the algorithm first checks whether the list is empty, and if so, returns that the only subset is the null set.
There are some ways the function can be improved. The biggest thing is that it calls getAllSubsets(lst[1:] twice. Unless you have a really smart compiler/interpreter that can recognize that and only actually run it once, you're doing much more work than you need to. I think it's even more than twice as much work, because you're doubling the amount of work at each level of recursion. So if there are five levels of recursion, you'll be running the lowest level 32 times as much. You could also hardcode the first level of recursion by just taking the null set and the element, although that's somewhat abandoning the simplicity of a pure recursion algoritm.
def getAllSubsets(lst):
"""
lst: A list
Returns the powerset of lst, i.e. a list of all the possible subsets of lst
"""
if not lst:
return [[]]
# you can remove the above two lines if you're sure
# that the original call isn't on an empty list
tail = lst[1:]
if not tail:
return [[],[lst[0]]
tail_subsets = getAllSubsets(tail)
withFirst = [[lst[0]] + rest for rest in tail_subsets]
return tail_subsets + withFirst

Find minimum values of both "columns" of list of lists

Given a list like the next one:
foo_list = [[1,8],[2,7],[3,6]]
I've found in questions like Tuple pairs, finding minimum using python and
minimum of list of lists that the pair with the minimum value of a list of lists can be found using a generator like:
min(x for x in foo_list)
which returns
[1, 8]
But I was wondering if there is a similar way to return both minimum values of the "columns" of the list:
output = [1,6]
I know this can be achieved using numpy arrays:
output = np.min(np.array(foo_list), axis=0)
But I'm interested in finding such a way of doing so with generators (if possible).
Thanks in advance!
[min(l) for l in zip(*foo_list)]
returns [1, 6]
zip(*foo_list) gets the list transpose and then we find the minimum in both lists.
Thanks #mousetail for suggestion.
You can use two min() for this. Like -
min1 = min(a for a, _ in foo_list)
min2 = min(b for _, b in foo_list)
print([min1, min2])
Will this do? But I think if you don't want to use third party library, you can just use plain old loop which will be more efficient.

how do I append a list with two variables to another list that already has that list in it but with different values? python

I'm doing my programming coursework, and I've come across an issue
gamecentre1 = [winnerscore, winner]
organise = []
organise.extend([gamecentre1])
from operator import attrgetter, itemgetter
sorted(organise, key= itemgetter(0))
print(organise)
f = open("gameresults.txt","w")
f.write("Here are the winners of the games: \n")
f.write(str(organise))
f.write("\n")
f.close()
I'm trying to add two variables to a list, and add that list to another list. Then, I want to organise that larger list based off of the integer variable of the sublist (the integer is the winnerscore). But, the problem is that I haven't been able to organise them properly, and I worry that since I have to append the same list with the same variables to the larger list without overwriting the existing list in it, the larger list will just have the same values over and over again.
This is because I want to store the variables every time the program runs, without getting rid of the values of the variable from the previous game.
How do I do this?
I'm trying to add two variables to a list, and add that list to another list. Then, I want to organise that larger list based off of the integer variable of the sublist
It sounds like what you want is a nested list - a big list of small lists, such that each small list is independent of the others. The key problem in your code right now that's blocking you from accomplishing this is extend() - this is essentially list concatenation, which isn't what you want. For example,
x = [1, 2]
x.extend([3, 4]) # x == [1, 2, 3, 4]
Instead, try using append(), which adds its argument as the next value in the list. For example:
x = []
x.append([3, 4]) # [[3, 4]]
x.append([1, 2]) # [[3, 4], [1, 2]]
Now in the above example, we have a list x that's two elements long, and each of those elements is itself a list of two elements. Now we can plug that into sort:
y = sorted(x, key=lambda i: i[0])
print(y)
# [[1, 2], [3, 4]]
(the lambda i: i[0] is really just a more elegant way of what you're doing with itemgettr(0) - it's a lambda, a small inline function, that takes one argument i and returns the 0th element of i. In this case, the i that gets passed in is one of the smaller lists).
Now you have a sorted list of smaller lists, and you can do whatever you need with them.

Where am I wrong?

Question
Write function mssl() (minimum sum sub-list) that takes as input a list of integers.It then computes and returns the sum of the maximum sum sub-list of the input list. The maximum sum sub-list is a sub-list (slice) of the input list whose sum of entries is largest. The empty sub-list is defined to have sum 0. For example, the maximum sum sub-list of the list [4, -2, -8, 5, -2, 7, 7, 2, -6, 5] is [5, -2, 7, 7, 2] and the sum of its entries is 19.
l = [4, -2, -8, 5, -2, 7, 7, 2, -6, 5]
mssl(l)
19
mssl([3,4,5])
12
mssl([-2,-3,-5])
0
In the last example, the maximum sum sub-list is the empty sub-list because all list items are
negative.
THIS IS MY SOLUTION
def mssl(lst):
pos,neg,TotalList=[],[],[]
for items in range(len(lst)):
if(lst[items]>0):
pos+=[lst[items]]
else:
neg+=[lst[items]]
TotalPos=sum(pos)
TotalNeg=sum(neg)
if(len(neg)>0):
for negatives in range(len(neg)):
TotalList=[TotalPos+neg[negatives]]
if(TotalList>TotalList[negatives-1]):
print(TotalList)
else:
TotalList=TotalPos
print(TotalList)
THIS IS NOT A HOMEWORK QUESTION I AM LEARNING PYTHON FOR FUN, PLEASE LET ME KNOW WHERE I AM WRONG
It looks like you're trying to learn programming, with python as your first language. This particular problem is a somewhat difficult one to start with. I would advise you to take a straightforward, brute-force approach at first. Evaluate the sums of all the subsequences, one after another, and keep track of which is largest. Once you have a function that will produce the correct answer, you can look for a better (faster, more elegant, whatever) solution.
As to your code, it really has nothing to do with the question. For example, TotalList is always a one-element list. The expression TotalList[negatives-1] doesn't make much sense; if there's only one element in the list, you can access it as TotalList[0]. The expression TotalList>TotalList[negatives-1] makes no sense at all; you don't want to compare a list to a number.
This is a well-known problem, and a simple, fast solution is not at all easy to come up with, so don't be discouraged if you don't find it. Once you get a straightforward solution, you can think about an elegant one. This problem can be solved in one line of python, using list comprehensions. Trying to do that will lead to improvement in your python style. For example, instead of writing
for items in range(len(lst)):
if(lst[items]>0):
pos+=[lst[items]]
else:
neg+=[lst[items]]
you can, and should write
pos = [x for x in lst if x > 0]
neg = [x for x in lst if x < 0]
Good luck learning python.

Swapping maximum and minimum values in a list

Given a list (for instance, [1,1,2,1,2,2,3]) which is not sorted highest to lowest, and contains multiples of all numbers, I need to swap, in place, the maximums with the minimums, the second maxes with the second mins, etc. So, our example list would become [3,3,2,3,2,2,1].
Also, just to clarify, it's not just the max and min, but each layer of maxes and mins. So if the max was 4, 1's and 4's should switch as well as 2's and 3's.
I found this question on the topic: How to swap maximums with the minimums? (python)
but the code examples given seemed verbose, and assumed that there were no duplicates in the list. Is there really no better way to do this? It seems like a simple enough thing.
This is one way to do it, possible because Python is such an expressive language:
>>> a = [1,1,2,1,2,2,3]
>>> d = dict(zip(sorted(set(a)), sorted(set(a), reverse=True)))
>>> [d[x] for x in a]
[3, 3, 2, 3, 2, 2, 1]

Categories

Resources