How can I find the missing value more concisely? How can I find the missing value more concisely? python python

How can I find the missing value more concisely?


z = (set(("a", "b", "c")) - set((x, y))).pop()

I am assuming that one of the three cases in your code holds. If this is the case, the set set(("a", "b", "c")) - set((x, y)) will consist of a single element, which is returned by pop().

Edit: As suggested by Raymond Hettinger in the comments, you could also use tuple unpacking to extract the single element from the set:

z, = set(("a", "b", "c")) - set((x, y))


The strip method is another option that runs quickly for me:

z = 'abc'.strip(x+y) if x!=y else None


Sven's excellent code did just a little too much work and chould have used tuple unpacking instead of pop(). Also, it could have added a guard if x != y to check for x and y being distinct. Here is what the improved answer looks like:

# create the set just oncechoices = {'a', 'b', 'c'}x = 'a'y = 'b'# the main code can be used in a loopif x != y:    z, = choices - {x, y}

Here are the comparative timings with a timing suite to show the relative performance:

import timeit, itertoolssetup_template = '''x = %ry = %rchoices = {'a', 'b', 'c'}'''new_version = '''if x != y:    z, = choices - {x, y}'''original_version = '''if x == 'a' and y == 'b' or x == 'b' and y == 'a':    z = 'c'elif x == 'b' and y == 'c' or x == 'c' and y == 'b':    z = 'a'elif x == 'a' and y == 'c' or x == 'c' and y == 'a':    z = 'b''''for x, y in itertools.product('abc', repeat=2):    print '\nTesting with x=%r and y=%r' % (x, y)    setup = setup_template % (x, y)    for stmt, name in zip([original_version, new_version], ['if', 'set']):        print min(timeit.Timer(stmt, setup).repeat(7, 100000)),        print '\t%s_version' % name

Here are the results of the timings:

Testing with x='a' and y='a'0.0410830974579     original_version0.00535297393799    new_versionTesting with x='a' and y='b'0.0112571716309     original_version0.0524711608887     new_versionTesting with x='a' and y='c'0.0383319854736     original_version0.048309803009      new_versionTesting with x='b' and y='a'0.0175108909607     original_version0.0508949756622     new_versionTesting with x='b' and y='b'0.0386209487915     original_version0.00529098510742    new_versionTesting with x='b' and y='c'0.0259420871735     original_version0.0472128391266     new_versionTesting with x='c' and y='a'0.0423510074615     original_version0.0481910705566     new_versionTesting with x='c' and y='b'0.0295209884644     original_version0.0478219985962     new_versionTesting with x='c' and y='c'0.0383579730988     original_version0.00530385971069    new_version

These timings show that the original-version performance varies quite a bit depending on which if-statements are triggered by the various the input values.