-2

I have a list which stores scores of a game which is played in rounds. At each index, the score is stored such that it's equal to the total score scored up to and including that round.

  • round 1 - 5 points are scored in this round
  • round 2 - 3 points are scored in this round
  • round 3 - 7 points are scored in this round
  • round 4 - 4 points are scored in this round

This will result in

total_score = [5, 8, 15, 19]

How can I convert this neatly into a list which has the score of each round at each index, instead of the total score up to that round.

So I want to turn the above list into:

round_scores = [5, 3, 7, 4]

It's not particularly hard to do with just iterating over it and subtracting the score at the previous index from the score at the current index. But is there a neater way to do this? Maybe a one liner list comprehension? I'm fairly new to Python but I've seen some magic being done in a single line in other answers.

Sam
  • 189
  • 5
  • 17
  • 1
    `res = [total_score[0]] + [x-y for x, y in zip(total_score[1:], total_score[:-1])]` there probably are prettier solutions as well – Ma0 Aug 06 '19 at 11:27
  • 3
    `a = np.array(total_score)` then `a[1:] -= a[:-1]` is a beautiful solution (not mine sadly) – Chris_Rands Aug 06 '19 at 11:35
  • That's a really nice solution, I only wish it worked on regular lists because creating that array takes longer than the actual solution that follows. – Sam Aug 06 '19 at 14:16

4 Answers4

1
x = [5, 8, 15, 19]  # total scores
y = [x[i] - x[i-1] if i else x[i] for i in range(len(x))]  # round scores
print(y)
# output
[5, 3, 7, 4]
dopstar
  • 1,478
  • 10
  • 20
1

Using numpy,

import numpy as np

total_score = [5, 8, 15, 19]
round_scores = np.diff(total_score, prepend=0)
happyweary
  • 81
  • 2
0

You can use zip with a list comprehension:

[total_score[0]] + [abs(x - y) for x, y in zip(total_score, total_score[1:])]

Example:

total_score = [5, 8, 15, 19]

print([total_score[0]] + [abs(x - y) for x, y in zip(total_score, total_score[1:])])
# [5, 3, 7, 4]
Austin
  • 25,759
  • 4
  • 25
  • 48
  • 1
    or for a smaller byte count `res = [x-y for x, y in zip(total_score, [0]+total_score)]` – Ma0 Aug 06 '19 at 11:29
  • 1
    also, I would not take the `abs`. If you score negative points, it has to show as such (and you can always reverse the order of the `zip`). – Ma0 Aug 06 '19 at 11:31
0

You could just iterate over the indices:

round_score = [total_score[0]]
round_score += [total_score[i] - total_score[i-1] for i in range(1, len(total_score))]

Or to make it in one expression with a little pre-processing:

temp = [0] + total_score

round_score = [temp[i] - temp[i-1] for i in range(1, len(temp))]
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61