a function like “sum” that instead of adding, subtracts
it’s easy to make a function like that in python, but It would save me a lot of work if they made this function
a function like “sum” that instead of adding, subtracts
it’s easy to make a function like that in python, but It would save me a lot of work if they made this function
Moving to help category because there are already plenty of solutions to this.
what solutions?
Could you show an example of the work you had to do because of it, and how you think it would be easier if you had access to this “sub”?
Could you show a detailed explanation of what the interface and semantics should be?
In particular, is there a reason why this is different from “the first element, minus the sum of the other elements”, which is trivial to express in terms of the existing sum
?
Ugly, but:
>>> sub = lambda x, *rest: x-sum(rest)
>>> sub(10000, 8)
9992
>>> sub(10000, 8, 2, 4)
9986
>>>```
That doesn’t take an iterable, unlike sum
.
Perhaps:
def sub(iterable):
iterator = iter(iterable)
try:
first = next(iterator)
except StopIteration:
raise ValueError # or return 0?
return first - sum(iterator)
@blhsing Another, which might differ less often from the normal left-to-right calculation:
def sub1(iterable):
iterator = iter(iterable)
try:
first = next(iterator)
except StopIteration:
raise ValueError # or return 0?
return first - sum(iterator)
def sub2(iterable):
iterator = iter(iterable)
for first in iterator:
return -sum(iterator, -first)
raise ValueError # or return 0?
a, b, c = iterable = 0.1, 0.2, 0.6
print(a - b - c)
print(sub1(iterable))
print(sub2(iterable))
Output (Attempt This Online!):
-0.7
-0.7000000000000001
-0.7
And with a, b, c = iterable = [1e308] * 3
:
-1e+308
-inf
-1e+308
Addition is associative, subtraction is not.
sum([1,2,3]) == (1 + 2) + 3 == 1 + (2 + 3) == 6
What should difference([1,2,3])
compute?
1 - (2 - 3) == 1 - (-1) == 2
, or(1 - 2) - 3 == -1 -3 == -4
, or-1 + -2 + -3 == -6
(for sake of argument; this isn’t really equivalent to what I think you want)Very good point, although if you want to be truly faithful to the original expression of a - b - c
you can use functools.reduce
and operator.sub
:
from operator import sub
from functools import reduce
def sub2(iterable):
iterator = iter(iterable)
for first in iterator:
return -sum(iterator, -first)
raise ValueError # or return 0?
def sub3(iterable):
iterator = iter(iterable)
for first in iterator:
return reduce(sub, iterator, first)
raise ValueError # or return 0?
a, b, c = iterable = -.0, -.0, -.0
print(a - b - c) # outputs 0.0
print(sub2(iterable)) # outputs -0.0
print(sub3(iterable)) # outputs 0.0
Yeah, that’s why I said “differ less often”
If you’re ok with reduce
’s TypeError for empty iterables, you can also just do
def sub4(iterable):
return reduce(sub, iterable)
It would not save a lot of work because it’s the same as x[0]-sum(x[1:]) or 2*x[0]-sum(x)