Некоторые для номера цикла уменьшаются, когда они должны увеличиваться при переборе списка - PullRequest
0 голосов
/ 28 ноября 2018

Я какое-то время просматривал свой код и просто застрял в том, где я все испортил, так что, возможно, один из вас может помочь.

То, что должен делать мой цикл for, это: он повторяет длинный список раз.Он усредняет первые 100 раз и устанавливает это значение.Эта часть работает.Затем он должен добавить единицу к t (значение, которое я использую для цикла for), так что это будет в среднем 1-й и 101-й раз вместе, если это среднее значение менее чем на 0,1 секунды быстрее, добавьте значение t ксписок значений х, затем установите это значение в качестве нового среднего для бить.Если оно не меньше .1, мы увеличиваем t и пробуем снова, пока оно не заработает.

Вот мой код, и я расскажу вам, что значит сделать его более читабельным

for t in times:
    t = int(t)
    sumset = sum(times[t:t + 100])
    avgset = (int(round(float(sumset/100), 3) * 10)) /10
    if t + 100 > len(times):
        break
    elif (avgset) <= firstavg - .1:
        avglist.append(avgset)
        firstavg -= .1
        xlist.append(t)
        print(t)
        print("avgset is "+str(avgset))
        print("should decrease by .1 " + str(math.ceil(firstavg * 10) / 10))
        tlist.append(t)
        t += 1
    else:
        t += 1

Я объясню здесь.

for t in times:
    t = int(t)
    sumset = sum(times[t:t + 100])
    avgset = (int(round(float(sumset/100), 3) * 10)) /10

для каждого значения в моем списке с именем times, мы берем значение и проверяем, что это int, я делаю это потому, что раньше у меня возникала проблема с индексацией, говоря, что это не int.Sumset получает сумму первых 100 раз, в которой мы нуждаемся, и avgset превращает ее в среднее значение, умножает ее на 10, использует int для отсечения десятичной дроби и делит на десять, чтобы получить десятое значение.

Пример

12.34 * 10 = 123.4, int(123.4) = 123, 123 / 10 is 12.3.

Тогда здесь

if t + 100 > len(times):
    break

Мы проверяем, что для итерации осталось 100 значений, если не мы завершим цикл.

На этом большом куске

elif (avgset) <= firstavg - .1:
    avglist.append(avgset)
    firstavg -= .1
    xlist.append(t)
    print(t)
    print("avgset is "+str(avgset))
    print("should decrease by .1 " + str(math.ceil(firstavg * 10) / 10))
    tlist.append(t)
    t += 1

Мы проверяем: если набор <= к первому среднему значению - .1, мы добавляем этот набор средних к списку понижающих средних.Затем мы уменьшаем первое среднее значение и добавляем значение t в список, который будет составлять наши значения x.Что он должен сделать, это произвести мне список значений x, где каждое значение соответствует уменьшению .1 от исходного среднего (t: t +100), где t равно 0. И мы получаем y-список (который будетavglist), который является каждым уменьшением .1.Я не уверен, где я запутался, поэтому, если кто-то может указать мне правильное направление, я был бы очень признателен, спасибо! </p>

1 Ответ

0 голосов
/ 28 ноября 2018

По моему мнению, в вашем коде есть несколько вещей, на которые следует обратить внимание:

1) Главное и самое важное, что вы смешиваете элементы в вашем списке (числа с плавающей запятой) с их индексами, т.е.позиции в списке.Вам нужно перебирать индексы, а не сами элементы.Я имею в виду, что с учетом списка:

my_list = [5.67, 4.23, 7.88, 9.5]

индексы [5.67, 4.23, 7.88, 9.5] соответственно: 0,1,2,3.Python хочет иметь целое число для повторения, потому что он интерпретирует эти числа как положение элементов в списке, независимо от их значения.И позиции, очевидно, всегда должны быть целыми числами, т.е. вы либо 4-й, либо 5-й, а не 4,23-й.Однако это НЕ означает, что значения самих элементов должны быть целыми числами.Для учета этой разницы есть встроенная функция python enumerate():

>>> for index, value in enumerate([5.67, 4.23, 7.88, 9.5]):
...    print (index, '->', value)
...    
0 -> 5.67
1 -> 4.23
2 -> 7.88
3 -> 9.5
>>>

, по этой причине вам нужно было преобразовать ваши значения (не индексы) в целые числа и сделать трюк умноженияи деление на 10, чтобы не потерять разрешение 0,1, которое вы используете для сравнения.Вы можете забыть обо всем этом.

2) Вам не нужно проверять каждую итерацию, осталось ли в списке 100 элементов или нет.Достаточно итерировать до -100-го элемента:

for index, time in enumerate(times[:-100]):

, и он автоматически остановится на -100-м.Однако, когда вы делаете это, помните, что вы хотите всегда использовать index в качестве переменной итератора, а не time.Более того, в другом цикле for вы можете использовать в другом случае, если вам нужно проверить, выполнено ли какое-либо условие для обработки текущего элемента, и если нет перехода к следующему, вы должны использовать continue вместо break:

for index, time in enumerate(times):
    if index+100 > len(times):
        continue

continue выводит вас из оператора if и приводит вас к циклу for, готовому выполнить итерацию со следующим элементом.break прервет цикл for и остановит итерацию.

3) В конце каждой из ваших итераций вы получите

elif (...):
    ...
    t += 1
else:
    t += 1

, что во многом неправильно:

3.1) сначала потому, что вы находитесь внутри итератора, а t относится к переменной, которую вы используете для итерации.Вам вообще не нужно указывать итератору сумму 1 к переменной итерации в конце каждой итерации.Делать это - это его единственная работа.Он знает.

3.2) Предполагая, что это будет любая другая переменная управления внутри цикла, которую вам действительно нужно вручную увеличить на единицу, вы повторяете строки кода.По сути, вы получите тот же эффект, если уберете предложение else и удалите отступ последней строки предложения elif:

elif (...):
    ...

t += 1

, поэтому алгоритм попадет в t +=1 относительно того,условие elif выполнено или не выполнено.

3.3) Это связано с вышеупомянутым пунктом 1): В вашем конкретном случае и поскольку вы ошибочно используете t для итерации (как обсуждалось выше),делая t += 1, вы изменяете список, по которому вы перебираете, то есть вы изменяете входные данные.

Принимая все это во внимание, одним из возможных способов грубой реализации вашего кода может быть:

import numpy as np

times = 100*np.random.rand(150)

list_of_avgs = [np.sum(times[:100])/100.]

for index, element in enumerate(times[:-100]):

    avg = np.sum(times[index:index+100])/100.

    if avg + 0.1 <= list_of_avgs[-1]:
        list_of_avgs.append(avg)
    else:
        continue

 print (list_of_avgs)

, что приводит к (исходные данные генерируются очень часто):

[49.779866192794358, 49.594673775689778, 49.4409179407875, 
49.304759324340424, 49.106580355542434, 48.651419303532919, 
48.505888846346672, 47.834645246733295, 47.300679740055074, 
46.956253292222293, 46.598627928361239, 46.427709019922297]

Приветствия и удачи!

D.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...