Reputation: 75
I'm trying to learn how to change this program into a for loop for the sake of knowing both ways
def Diff(a_list):
num = enumerate(max(x) - min(x) for x in a_list)
return max(x[::-1] for x in num)
I want it to be something like
def Diff(x):
for a in x
if it helps the program is intended to return the row that has the smallest sum of the elements inside it so like [[1,2,3,4],[-500],[10,20]]
would be 1
.
Upvotes: 0
Views: 140
Reputation: 126
if you're looking for minimum sum, just go through every row and keep track of the smallest:
def minRow(theList):
foundIndex = 0 # assume first element is the answer for now.
minimumSum = sum(theList[0])
for index, row in enumerate(theList):
if sum(row) < minimumSum:
foundIndex = index
minimumSum = sum(row) # you don't have to sum() twice, but it looks cleaner
return foundIndex
If your looking for greatest range (like the first Diff() function), it'd be similar. You'd keep track of the greatest range and return its index.
Thorsten's answer is very complete. But since I finished this anyway, I'm submitting my "dumbed down" version in case it helps you understand.
Upvotes: 0
Reputation: 9584
What you want can actually be done in two lines of code:
# Let's take the list from your example
lst = [[1,2,3,4],[-500],[10,20]]
# Create a new list holding the sums of each sublist using a list comprehension
sums = [sum(sublst) for sublst in lst]
# Get the index of the smallest element
sums.index(min(sums)) # Returns: 1
Upvotes: 0
Reputation: 12755
I do not understand why you use this name for your function, it does something else (as far as I understand). It searches for the inner-list inside a list for which the difference between min and max, the span, are maximal and the n returns a tuple (span, idx)
, idx
being the index within the outer loop.
When you want to have the same as a loop, try:
def minRow_loop(a_list):
rv = (0,0)
for idx, row in enumerate(a_list):
span = max(row) - min(row)
span_and_idx = (span, idx)
if span_and_idx > rv:
rv = span_and_idx
return rv
But your code doesn't do what it'S intended to do, so I created two correct versions, once with and once without a loop.
import random
random.seed(12346)
def minRow(a_list):
num = enumerate(max(x) - min(x) for x in a_list)
return max(x[::-1] for x in num)
def minRow_loop(a_list):
rv = (0,0)
for idx, row in enumerate(a_list):
span = max(row) - min(row)
span_and_idx = (span, idx)
if span_and_idx > rv:
rv = span_and_idx
return rv
def minRow_correct(a_list):
return min(enumerate([sum(l) for l in a_list]),
key=lambda (idx, val): val)[0]
def minRow_correct_loop(a_list):
min_idx = 0
min_sum = 10e50
for idx, list_ in enumerate(a_list):
sum_ = sum(list_)
if sum_<min_sum:
min_idx = idx
min_sum = sum
return min_idx
li = [[random.random() for i in range(2)] for j in range(3)]
from pprint import pprint
print "Input:"
pprint(li)
print "\nWrong versions"
print minRow(li)
print minRow_loop(li)
which prints:
Input:
[[0.46318380478657073, 0.7396007585882016],
[0.38778699106140135, 0.7078233515518557],
[0.7453097328344933, 0.23853757442660117]]
Wrong versions
(0.5067721584078921, 2)
(0.5067721584078921, 2)
Corrected versions
2
2
Upvotes: 1