Нужно отображать только текущий элемент вычисления itertools списка в Python - PullRequest
0 голосов
/ 29 марта 2019

При создании функции, которая вычитает числа из элемента (все данные пользователя и вычисляет непрерывно), компилятор отображает только все вычисленные элементы.

Попытка передачи счетчика в качестве аргумента функции вычитания, но независимо от того, что я пытаюсь сделать с циклом for, я получаю индекс ошибок за пределами границ

def number_list(operator_item): #Creates a list of numbers, after calculation, list is returned to main to be assigned to list_of_numbers variable
    number_list = []
    counter = 1
    print("Enter one value at a time and press enter, press = and enter to proceed")
    while number_list != "=": # Calculations are entered until the user types the equal sign, then the answer is returned to main

        try:
            list_value = float(input())
        except ValueError: # Used an exception to confirm sentinel value, this is to maintain accuracy with float number calculations. No error is handled unless "=" is not entered second time
            sentinel_value = input("Press '=' again to complete calculation and copy answer to system clipboard.\n\n") 
            if sentinel_value == "=":
                copy(running_total)
                return running_total
            else:
                print("Invalid entry!")

        number_list.append(list_value) #Each number that is input will be added to list 
        counter += 1

# I have functions for sum and product, but are excluded for relevance
        if operator_item == "-":
            running_total = subtraction(number_list, counter)
            print("Current difference:", running_total)


def subtraction(number_array, number_element):
    total = list(itertools.accumulate(number_array, operator.sub))
    return total

Вот мои реальные результаты компиляции.Я просто вычитаю 5 каждый раз.

Введите по одному значению за раз и нажмите ввод, нажмите = и введите, чтобы продолжить

5 (Это число, которое я ввожу на клавиатуре)

Разность токов: [5,0]

5 (Это число, которое я ввожу на клавиатуре)

Разность токов: [5,0, 0,0]

5(Это число, которое я ввожу на клавиатуре)

Текущая разница: [5.0, 0.0, -5.0]

Я ожидал, что это будет так:

Введите по одному значению за раз и нажмите ввод, нажмите = и введите, чтобы продолжить

5 (Это число, которое я ввожу на клавиатуре)

Разница тока: 5,0

5 (Это число, которое я ввожу на клавиатуре)

Разность тока: 0,0

5 (Это число, которое я ввожу на клавиатуре)

Разница тока: -5.0

Как мне заставить его обрезать скобки и все предыдущие элементы?

Ответы [ 2 ]

0 голосов
/ 29 марта 2019

Ну, ваша проблема в функции substraction.

Дело в том, что вы можете сделать это просто:

from operator import sub
from functools import reduce           # Python 3.x require this.

def substraction(number_list):         # You don't even need the counter param here.
    return reduce(sub, number_list)    # You don't need itertools neither.
0 голосов
/ 29 марта 2019

Причина такого поведения лежит в пределах itertools.accumulate.Давайте посмотрим на документы :

Создание итератора, который возвращает накопленные суммы или накопленные результаты других двоичных функций (указанных через необязательный аргумент func).

Что это значит?accumulate принимает итерируемое и функцию и применяет эту функцию к элементам итерируемого в определенном порядке, возвращая новый итерируемый, содержащий все результаты .Сначала он берет первый (два) элемент (ы), затем результат этого и третьего элемента, результат этого и четвертого элемента и т. Д. - вот что означает «накопительный расчет».Простой пример:

import itertools

def substraction(array):  # adding number_element as an argument is not needed
    total = list(itertools.accumulate(array, lambda x, y: x-y))
    return total

number_array = [5]
print(substraction(number_array))
# prints [5]  (5=5)

number_array.append(5)  # array is now [5, 5]
print(substraction(number_array))
# prints [5, 0]  (5=5, 5-5=0)

number_array.extend([-5, 4, 6])  # array is now [5, 5, -5, 4, 6]
print(substraction(number_array))
# prints [5, 0, 5, 1, -5]  (5=5, 5-5=0, 0-(-5)=5, 5-4=1, 1-6=-5)

Теперь, насколько я понимаю, вас интересует только последнее значение этого вычисления в любой точке.Существует модуль с именем functools, который имеет удобную функциональность для этого: functools.reduce:

Применить функцию двух аргументов кумулятивно к элементам последовательности слевавправо, чтобы уменьшить последовательность до одного значения.

Итак, еще раз, он будет кумулятивно вычитать числа слева направо, но вернет только текущий конечный результат в виде целого числа, что в точности то, что вы хотите.

import functools

def substraction(array):
    total = functools.reduce(lambda x, y: x - y, array)  # notice the reversed order of arguments, compared to itertools.accumulate
    return total

number_array = [5]
print(substraction(number_array))
# prints 5 (5=5)

number_array.append(5)
print(substraction(number_array))
# prints 0 ((5)-5=0)

number_array.extend([-5, 4, 6])
print(substraction(number_array))
# prints -5  (((((5)-5)-(-5))-4)-6=-5)
...