Kannan Ekanath
Kannan Ekanath

Reputation: 17601

Python converting nested loops to simple line

In Python 2.7.x I have two lists I would like a function that returns the first value (not index) as shown below

def first_incorrect_term(polynomial, terms):
    for index in range(len(polynomial), len(terms)):
        if evaluate(polynomial, index) != terms[index-1]:
            return evaluate(polynomial, index)

Let us assume evaluate is a function that works. I would like to replace these three lines which looks Object Oriented into something that uses the "find" or some such function in Python.

Basically I am iterating through the indices of the second list beyond the number terms in the polynomial (as I am confident the first X terms will match), evaluating it and comparing with the expected terms. For the first instance where the terms do not match I would like the evaluated polynomial returned.

I am looking for a replacement of these 3 lines using a Python find/lambda or some such thing, this is because I can definitely see I am not using the Python power as described for example in the link

PS: This is somewhat related to a Project Euler problem, however I have solved it using the snippet above and would like to improve my "Python" skills :)

Upvotes: 1

Views: 347

Answers (2)

Phil H
Phil H

Reputation: 20141

Firstly, use yield to make a generator version of your function:

def incorrect_terms(polynomial, terms):
    for index in range(len(polynomial), len(terms)):
        eval = evaluate(polynomial,index)
        if eval != terms[index-1]:
            yield (polynomial, index, eval)

Then the first result is the first mismatch:

mismatches = incorrect_terms(polynomial, terms)
first_mismatch = mismatches.next()

I think you actually want to iterate over all the values of terms, not the values after polynomial's length, in which case you can zip:

results = (evaluate(polynomial,index) for index in count(0))
pairsToCompare = itertools.izip(results, terms)
mismatches = (pair for pair in pairsToCompare if pair[0] != pair[1])

first_mismatch = mismatches.next()

Assuming here that evaluate(polynomial, n) is calculating the nth term for a given polynomial, and that these are being compared with the values in terms.

Upvotes: 1

glglgl
glglgl

Reputation: 91039

I would do it using generator expressions, but they don't fit in one line as well:

def first_incorrect_term(polynomial, terms):
    evaled = ((index, evaluate(polynomial, index)) for index in range(len(polynomial), len(terms)))
    return next((val for index, val in evaled if val != terms[index-1]), None)

Upvotes: 0

Related Questions