0

I'm trying to calculate, with a loop, a substraction between n element and n+1 element inside a single python list.

For exemple :

list = [26.5, 17.3, 5.9, 10.34, 3.87]

    # expected calculation
    # 26.5 - 17.3 = 9.2
    # 17.3 - 5.9 = 11.4
    # ...

    # expected result
    # list_2 = [9.2, 11.4, -4.44, 6.47]

I tried with :

list_2 = [n-(n+1) for n in list]
    # output
    # [-1.0, -1.0, -1.0, -1.0, -1.0]

-----------------------------------------
list_2 = []
for n in list:
    list_2 += list[n] - list[n+1]
    # output
    # TypeError: list indices must be integers or slices, not float
    
    # with correction of 'TypeError'
    list_2 += list[int(n)] - list[int(n+1)]
    # output
    # TypeError: 'float' object is not iterable

The problem look simple but... I can't do it. Do you have an idea? If it is possible, I'm looking for a native python3 solution.

Thank you per advance and have a nice day/evening.

Tim
  • 39
  • 6
  • 2
    a couple of functions that you might find useful: `zip`, and `enumerate`. Also you should read and understand what you get when doing `for x in y` (hint: x is not an index) – njzk2 Sep 13 '22 at 16:41

3 Answers3

2

You can use zip and slice, here is the respective documentation from the official https://docs.python.org site:

Documentation for the zip function:

 zip(*iterables, strict=False)

Iterate over several iterables in parallel, producing tuples with an item from each one.

Code

>>> l = [26.5, 17.3, 5.9, 10.34, 3.87]
>>> result = [current-_next for current,_next in zip(l,l[1:])]
>>> result
[9.2, 11.4, -4.4399999999999995, 6.47]

NOTE: The third result is unprecise because of floating point math

Alternative?

As an alternative, you can also do this as an iterable using itertools.starmap and operator.sub:

>>> from operator import sub
>>> result = itertools.starmap(sub,zip(l,l[1:]))
XxJames07-
  • 1,833
  • 1
  • 4
  • 17
1

Try this.

l = [26.5, 17.3, 5.9, 10.34, 3.87]

result = [l[i] - l[i + 1] for i in range(len(l) - 1)]
Ankit Sharma
  • 1,626
  • 1
  • 14
  • 21
  • Very nice and elegant solution. It works perfectly. I don't really know why because it looks similar to "list_2 += list[in] - list[n+1]" but anyway ! I just add a round() method to your solution. Thank you very much ! – Tim Sep 13 '22 at 16:58
1

@Ankit Sharma's answer works perfectly, as does @XxJames07-'s. Personally, I prefer using enumerate() rather that range(len) or zip in such situations. For example:

>>> l = [26.5, 17.3, 5.9, 10.34, 3.87]
>>> result = [n - l[i + 1] for i, n in enumerate(l[:-1])]
>>> print(result)
[9.2, 11.4, -4.4399999999999995, 6.47]


This is simply because it's more "pythonic", i.e. it has cleaner syntax, can work with any iterable, can access both value and index, and it is more optimised (wastes less resources on the computer). Here's a good explanation.

This solution is also simpler and more readable than using zip, which is a tad bit unnecessarily complicated for a simple problem.

user17301834
  • 443
  • 1
  • 8