Python для циклов, не повторяющих корректно второе условие - PullRequest
0 голосов
/ 16 мая 2018

У меня есть длинный список кортежей, которые принимают форму

num_list = [('A1', 4, 'FF', 977.98), ('A4', 14, 'CC', 249.12), ('A1', 14, 'EE', 386.42), ('A9', 19, 'BB', 919.21), ('A4', 14, 'CC', 109.80)]

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

Задача состоит в том, чтобы распечатать максимальное значение за предыдущие 5 дней, например, на 6-й день следует рассматривать только события от 1 до 5 дней для каждого отдельного идентификатора, т.е.базовой формы

Day   ID    Max
7     A1    400
7     A2    350
8     A1    750

В настоящее время у меня есть следующий код после объявления num_list, где ID - это набор всех значений ID.14 и 18 используются по мере приближения дней к 19

first_value = 1
fifth_value = 5

for id in ID:
    while first_value <= 14 and fifth_value <= 18:
        result = max([i for i in num_list if i[1] <= fifth_value and i[1] >= first_value and i[0] == id], key = lambda  x:x[3])
        first_value += 1
        fifth_value += 1
        print(f"result[0]} {result[1]} {result[3]}")   

Проблема заключается в том, что это возвращает только максимальные результаты для первого идентификатора, в данном случае A1.Это он делает правильно, но я не уверен, почему он не делает это для каждого удостоверения личности.Я проверил и перед циклом while он возвращает каждый идентификатор, поэтому я не уверен, в чем здесь проблема

Заранее спасибо, извините, если что-то подобное было опубликовано ранее, но я не смог его найти

Ответы [ 3 ]

0 голосов
/ 17 мая 2018

Во-первых, в этой строке отсутствует открывающая фигурная скобка для result[0] print(f"result[0]} {result[1]} {result[3]}") но ваша главная проблема заключается в том, что в вашем цикле while значения first_value и fifth_value продолжают увеличиваться, пока цикл while выполняется для первого идентификатора, но затем они никогда не сбрасываются, поэтому для каждого последующего идентификатора вы никогда не входите в цикл while.

0 голосов
/ 17 мая 2018

Я не уверен, что вы ищете, но вот мои 2 цента.Обратите внимание, что id является зарезервированным именем переменной в Python.(отсюда использование id_)

#Let's say we have the data shown in the `num_list`.

num_list = [('A1', 4, 'FF', 977.98), ('A4', 14, 'CC', 249.12), ('A1', 14, 'EE', 386.42), ('A9', 19, 'BB', 919.21), ('A4', 14, 'CC', 109.80), ('A7', 6, 'DD', 243.12), ('A3', 11, 'GG', 612.21)]

#First, we want to sort it by the `day` of occurence. Then we want to list all the possible IDs.

sorted_list = sorted(num_list, key=lambda x:x[1])
ID = sorted(list(set(x[0] for x in num_list)))

# Then, let's define a function, which will get the entry/row with the maximum value
# We give the function two arguments. The `day`, which is the day of observation.
#    If the day of observation is 6, then, only look at the entries which have day of the event 1-5
# The another argument is the id_ we are looking at ('A1', 'A4', ..etc.)

def get_max_within_time_window(day, id_):

    # Get all the entries with the wanted id
    entries_id = [x for x in sorted_list if x[0] == id_]

    # Get all the entries within the 5-day time window. The day of observation not included.
    entries_filtered = [x for x in entries_id if 0 < day-x[1] <= 5]

    # In case of zero matches, return empty list
    if not entries_filtered:
        return []

    # Return the event with highest `value`
    return max(entries_filtered, key=lambda x:x[3])

# Now, let's put this in action.
# Day*: The day of observation
# Day: The day of event occurence. If day of observation is 6, then day of occurence can be 1, 2, 3, 4 or 5.
print('Day*\tDay\tID\tMax')
for day in range(20):
    for id_ in ID:
        found = get_max_within_time_window(day, id_)
        if not found:
            continue
        max_val = found[3]
        day_occured = found[1]
        print(f'{day}\t{day_occured}\t{id_}\t{max_val}')

Результаты

Day*    Day     ID      Max
5       4       A1      977.98
6       4       A1      977.98
7       4       A1      977.98
7       6       A7      243.12
8       4       A1      977.98
8       6       A7      243.12
9       4       A1      977.98
9       6       A7      243.12
10      6       A7      243.12
11      6       A7      243.12
12      11      A3      612.21
13      11      A3      612.21
14      11      A3      612.21
15      14      A1      386.42
15      11      A3      612.21
15      14      A4      249.12
16      14      A1      386.42
16      11      A3      612.21
16      14      A4      249.12
17      14      A1      386.42
17      14      A4      249.12
18      14      A1      386.42
18      14      A4      249.12
19      14      A1      386.42
19      14      A4      249.12
0 голосов
/ 16 мая 2018

На вашем примере я могу довольно легко получить доступ к любому диапазону кортежей:

#!/usr/bin/python

num_list = [('A1', 4, 'FF', 977.98), ('A4', 14, 'CC', 249.12), ('A1', 14, 'EE', 386.42), ('A9', 19, 'BB', 919.21), ('A4', 14, 'CC', 109.80)]

print [item for item in num_list if item[1] < 19 ]

Вывод:

mortiz@alberta:~/Documents/projects/python$ python tuples.py 
[('A1', 4, 'FF', 977.98), ('A4', 14, 'CC', 249.12), ('A1', 14, 'EE', 386.42), ('A4', 14, 'CC', 109.8)]

Если вы хотите диапазон, то измените его, используя диапазон ():

print [item for item in num_list if item[1] in range(5,19) ]

Выход:

mortiz@alberta:~/Documents/projects/python$ python tuples.py 
[('A4', 14, 'CC', 249.12), ('A1', 14, 'EE', 386.42), ('A4', 14, 'CC', 109.8)]

Наконец, самое высокое значение выбранного диапазона:

#!/usr/bin/python

num_list = [('A1', 4, 'FF', 977.98), ('A4', 14, 'CC', 249.12), ('A1', 14, 'EE', 386.42), ('A9', 19, 'BB', 919.21), ('A4', 14, 'CC', 109.80)]
result=[item for item in num_list if item[1] in range(5,19)]
highest=[item[3] for item in result]

print max(highest)

Выход (максимальное значение)

mortiz@alberta:~/Documents/projects/python$ python tuples.py
386.42

Это то, что вы хотите?

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