JGrazza
JGrazza

Reputation: 75

How to write this program into a for loop?

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

Answers (3)

Jeremy SH
Jeremy SH

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

pemistahl
pemistahl

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

Thorsten Kranz
Thorsten Kranz

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

Related Questions