Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looking for a more pythonic logical solution

Tags:

python

logic

I was doing some practice problems in Coding Bat, and came across this one..

Given 3 int values, a b c, return their sum. However, if one of the values is the same as another of the values, it does not count towards the sum. 

lone_sum(1, 2, 3) → 6
lone_sum(3, 2, 3) → 2
lone_sum(3, 3, 3) → 0 

My solution was the following.

def lone_sum(a, b, c):
   sum = a+b+c
   if a == b:
     if a == c:
         sum -= 3 * a
     else:
         sum -= 2 * a
   elif b == c:
     sum -= 2 * b
   elif a == c:
     sum -= 2 * a
   return sum

Is there a more pythonic way of doing this?

like image 621
mankand007 Avatar asked May 30 '12 12:05

mankand007


4 Answers

Another possibility that works for an arbitrary number of arguments:

from collections import Counter

def lone_sum(*args):
    return sum(x for x, c in Counter(args).items() if c == 1)

Note that in Python 2, you should use iteritems to avoid building a temporary list.

like image 164
Niklas B. Avatar answered Sep 30 '22 14:09

Niklas B.


How about:

def lone_sum(*args):
      return sum(v for v in args if args.count(v) == 1)
like image 35
Roger Avatar answered Sep 30 '22 15:09

Roger


A more general solution for any number of arguments is

def lone_sum(*args):
    seen = set()
    summands = set()
    for x in args:
        if x not in seen:
            summands.add(x)
            seen.add(x)
        else:
            summands.discard(x)
    return sum(summands)
like image 41
Sven Marnach Avatar answered Sep 30 '22 14:09

Sven Marnach


Could use a defaultdict to screen out any elements appearing more than once.

from collections import defaultdict

def lone_sum(*args):
  d = defaultdict(int)
  for x in args:
    d[x] += 1

  return sum( val for val, apps in d.iteritems() if apps == 1 )
like image 43
Agent Lenman Avatar answered Sep 30 '22 13:09

Agent Lenman