Home > front end >  Write to console only if any() function returns false
Write to console only if any() function returns false

Time:03-18

Long time haven't used python, so don't laugh.

I have two lists which I am comparing:

list_1, list_2 = [sorted(l, key=itemgetter("someKey"))
                  for l in (list_1, list_2)]

pairs = zip(list_1, list_2)
return any(x != y for x, y in pairs)

How to best modify the code so that when it find a pair that does not match (2 items doesn't equal each other), it will print out this NOT matching pair.

I know it could be done using for loop, but is there a better simpler way here ?

CodePudding user response:

The least verbose way I can think of is probably

return next(((x, y) for (x, y) in pairs if x != y), 'All Pairs Match')

what this does is pipe the generator comprehension (x, y) for (x, y) in pairs if x != y into next(), which will return the first element it produces (i.e. the first case for which x != y), or if that never happens, will return the default 'All Pairs Match' (or whatever else it is you want to return if the two lists are the same).

next() is designed mostly to be used inside while loops for taking items one-by-one from an iterator at need, but we can also use it for things like this when we only need to know the first element in a collection that meets a condition.

CodePudding user response:

Since you have a return, I assume you have a function definition like

def foo(list_1, list_2):
    pairs = zip(list_1, list_2)
    return any(x != y for x, y in pairs)

Once the function returns, it's too late to see what made any return False, so we'll have to save the return value before actually returning.

We can, however, make use of assignment expressions to save the last values assigned to x and y before any stopped iterating over pairs.

def foo(list_1, list_2):
    pairs = zip(list_1, list_2)
    if rv := any((x0:=x) != (y0:=y) for x, y in pairs):
        print(x0, y0)
    return rv

x0 and y0 repeatedly get assigned new values as the iteration proceeds, but are not local to the generator expression as x and y are, so we can look at there values after any returns. (Likewise, rv saves the return value of any so that regardless of what any returns, foo can return that value after the if statement completes.)

Use cases like this are precisely why assignment expressions are scoped the way they are.

There is one special case: an assignment expression occurring in a list, set or dict comprehension or in a generator expression (below collectively referred to as “comprehensions”) binds the target in the containing scope, honoring a nonlocal or global declaration for the target in that scope, if one exists.

not the scope of the generator expression itself.

  • Related