The easiest and most reliable way is a naive solution with a counter and a cycle. But this is not our method. To start the text, then the code.
Take this array as an example: [-3, -4, 5, -5, 0, 3, -3] and leave only their sign instead of the numbers themselves: 1 for positive, -1 for negative: [-1, -1, 1, -1, 1, 1, -1] . Now we will take successively two adjacent numbers (their signs). This is what the sequence will look like:
-3, -4 (-1, -1); -4, 5 (-1, 1); 5, -5 (1, -1); -5, 0 (-1, 1); 0, 3 (1, 1); 3, -3 (1, -1).
Such pairs of numbers will be exactly len(list) - 1 , i.e. the length of the list is minus 1. Imagine that all numbers are positive. Then the sum of all pairs of characters (ie, units) will be equal to (len(list) - 1) * 2 . It is good if you do not just take a word, but check out this thesis. Each pair of numbers with different characters reduces the sum by 2. Denote the sum of these pairs of characters as summ and based on the above, the number of character shifts will be equal to ((len(list) - 1) * 2 - summ) / 2 . Let's write the sum as the sum of array elements with indices: summ: = | a 0 + a 1 | + | a 1 + a 2 | + | a 2 + a 3 | + | a 3 + a 4 | + | a 4 + a 5 | + | a 5 + a 6 |, where |...| - is the modulus of the number On this, in general, and all:
import random # Все, что касается знаков спихиваем на библиотеку # Ибо можно попасть на всякие нехорошие вещи типа -0.0, nan, -nan и т.д. # Однако copysign вычисляет в процессе арктангенс(!!!) от числа и нельзя сказать, что # это очень быстро. Для ультра быстроты можно поиграть с битовыми сдвигами from math import copysign LIST_LEN = 7 target_list = [random.randint(-15, 15) for _ in range(LIST_LEN)] only_ones_list = [copysign(1, element) for element in target_list] summ = 0 for i in range(len(only_ones_list) - 1): summ += abs(only_ones_list[i] + only_ones_list[i + 1]) sign_change_count = ((len(only_ones_list) - 1) * 2 - summ) / 2 print(target_list) print(only_ones_list) print(sign_change_count) >>> [-6, 12, -3, -11, -12, -13, 7] >>> [-1, 1, -1, -1, -1, -1, 1] >>> 3.0
The list of characters can not be compiled, of course, but immediately go through the original.
Now the most difficult thing is how this can be useful. First, there is no reasoning about zero-value or nan or anything else. We use the standard function and do not steam. Theoretically, you can do without conditional operators (inside abs and copysign) - you can try to calculate the sign and the module of the number using tricky bit operations. Theoretically, addition is also faster than multiplication, but the difference will be noticeable on large arrays.