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.