2012-05-30 2 views
6

я делал некоторые проблемы практики в Coding Bat, и наткнулся на этот ..Глядя на более вещий логическое решение

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 

Мое решение было следующее.

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 

Есть ли более питонический способ сделать это?

+1

Что касается кода отступы, посмотрите на эту http://stackoverflow.com/editing-help. Или нажмите? значок в верхней части окна редактирования. – mhawke

+0

@mhawke: Я следовал за 4-мя отступом, но в предварительном просмотре он не показывал никаких дополнительных отступов, поэтому немного запутался. Благодарим за редактирование кода! – mankand007

+0

благодарю Мартина за уборку! – mhawke

ответ

7

Как насчет:

def lone_sum(*args): 
     return sum(v for v in args if args.count(v) == 1) 
+1

Для трех аргументов эта реализация может быть прекрасной, но ее нельзя использовать для большего количества аргументов, так как это O (n²). И это полностью ускользает от меня, почему «без какого-либо импорта» следует считать преимуществом само по себе. –

+1

@SvenMarnach: Возможно, вы правы, но это идеальный ответ на вопрос OP. – BandGap

+0

@BandGap: Мне нравится отвечать Никласу лучше всего. Это так же коротко, как и чтение и O (n). –

8

Более общее решение для любого числа аргументов

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) 
+0

Интересное решение. +1 –

+0

Не работает для 'lone_sum (3, 3, 3)'; вам нужно добавить чек перед удалением из слагаемых. –

+0

@ SanjayT.Sharma: Была версия с этой проблемой в течение минуты или около того, но текущая версия в порядке. –

13

Еще одна возможность, которая работает для произвольного числа аргументов:

from collections import Counter 

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

Обратите внимание, что в Python 2, вы должны использовать iteritems для избегайте создания временного списка.

+0

Стоит отметить, что счетчик доступен только в Python> = 2.7 –

+2

@ Daniel: Python 2.7 теперь должен быть стандартным, я обычно предполагаю, что он доступен. Если 'Counter' недоступен, вы можете легко создать эквивалентную версию, используя' defaultdict (int) ' –

+1

@NiklasB. Я бы рискнул предположить, что многие пользователи Apple все еще работают 2.6 или ниже. Apple только обновила до 2.7 с помощью OSX 10.7. – senderle

2

Можете использовать defaultdict, чтобы отображать любые элементы, появляющиеся более одного раза.

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) 
+0

Это похоже на дух подхода Никласа Б - его также более кратким. –

+0

Также начните использовать 4-хпозиционное отступы в Python! См. PEP-8 по этой причине. – jamylak

Смежные вопросы