1

There are two non-empty lists, containing only ints, both have the same length.

Our function needs to return the average absolute difference between ints of same index.
For example, for the lists [1, 2, 3, 4] and [1, 1, 1, 1], the answer will be 1.5.
The function needs to be completed in one line.

I had a little something that does that, but as you can probably guess, it's not a one-liner:

def avg_diff(a, b):
    sd = 0.0
    for x, y in zip(a, b):
        sd += abs(x - y)
    return sd / len(a)

Thanks.

wohe1
  • 755
  • 7
  • 26
Guy
  • 29
  • 1
  • 3

4 Answers4

4

In Python 3.4 we got some statistic functions in the standard library, including statistics.mean.

Using this function and a generator-expression:

from statistics import mean

a = [1, 2, 3, 4]
b =  [1, 1, 1, 1]

mean(abs(x - y) for x, y in zip(a, b))
# 1.5
Graipher
  • 6,891
  • 27
  • 47
  • I *hate* the statistics module. If you look at the code it's insanely complex and has the really strange requirement that the precision of the result is equal to the precision of the inputs, something we very rarely care about in statistics. `from statistics import mean as stats_mean` --- `def py_mean(x): return sum(x) / len(x)` --- `%timeit stats_mean(x) # 137 ms ± 1.63 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)` --- `%timeit py_mean(x) # 359 µs ± 4.44 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)` – FHTMitchell Apr 06 '18 at 10:50
  • @FHTMitchell I admit to not using it normally, either, because I usually have `numpy.array`s. I just knew that it existed and it does make for a nice one-line solution, as requested by OP. I guess the price for it also supporting `Decimal` and `Fraction` is that insanely complex implementation and a speed-hit compared to the straight-forward implementation. – Graipher Apr 06 '18 at 10:53
  • 1
    Yeah same, I just think it's another case of the stdlib trying to include something currently done by a third party but somehow managing to do it much worse -- see `attrs` and `dataclasses`. For reference `%timeit np_mean(x) # 2.31 ms ± 41.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)`but that does have a list passed to it. For an array: `%timeit np_mean(y) # 63.1 µs ± 1.57 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)` – FHTMitchell Apr 06 '18 at 10:55
3
a = [1, 2, 3, 4]
b = [1, 1, 1, 1]

sum([abs(i - j) for i, j in zip(a,b)]) / float(len(a))
shahaf
  • 4,750
  • 2
  • 29
  • 32
2

If you are happy to use a 3rd party library, numpy provides one way:

import numpy as np

A = np.array([1, 2, 3, 4])
B = np.array([1, 1, 1, 1])

res = np.mean(np.abs(A - B))
# 1.5
jpp
  • 159,742
  • 34
  • 281
  • 339
0

Using the in-built sum and len functions on list:

lst1 = [1, 2, 3, 4]
lst2 = [1, 1, 1, 1]
diff = [abs(x-y) for x, y in zip(lst1, lst2)]  # find index-wise differences
print(sum(diff)/len(diff))    # divide sum of differences by total
# 1.5
Austin
  • 25,759
  • 4
  • 25
  • 48