Good solution. I got a cleaner version here.

class Solution(object):
def combinationSum2(self, candidates, target):
candidates.sort()
dp = [set() for i in xrange(target+1)]
dp[0].add(())
for num in candidates:
for t in xrange(target, num-1, -1):
for prev in dp[t-num]:
dp[t].add(prev + (num,))
return list(dp[-1])

For the uninitiated, basically, this problem is a variant of the knapsack problem. If you can understand the solution to Coin Change or Coin Change 2, then you can easily understand this solution. One caveat here is that the inner loop is reversed for t in xrange(target, num-1, -1), because each number can only be used once.

Food for thought - what happens if we don't reverse the inner loop? Can that be used to solve Combination Sum?