【问题标题】:Python for loops not iterating over 2nd condition correctlyPython for 循环未正确迭代第二个条件
【发布时间】:2018-10-27 00:08:55
【问题描述】:

我有一长串采用这种形式的元组

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)]

每个元组的第一个元素对应一个ID,第二个是事件发生的日期,第三个是事件的类别,第四个是事件的值。

任务是打印前 5 天的最大值,例如在第 6 天,对于每个单独的 ID,即基本形式的东西,只应考虑第 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]}")   

问题在于这仅返回第一个 ID 的最大结果,在本例中为 A1。这是正确的,但我不确定为什么它不是为每个 ID 都这样做。我已经检查过,在 while 循环之前它会返回每个 ID,所以我不确定这里的问题是什么

先谢谢了,如果以前发布过类似的东西,我很抱歉,但我找不到它

【问题讨论】:

  • 您的f 字符串中没有{ 吗?
  • 我添加了一些sn-p 代码来查找某天范围内的最大值。希望你看看它。

标签: python list for-loop while-loop tuples


【解决方案1】:

通过您的示例,我可以很容易地访问任何范围的元组:

#!/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)]

如果你想要一个范围,然后使用 range() 更改它:

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

这是你想要的吗?

【讨论】:

    【解决方案2】:

    首先,您在此行中缺少 result[0] 的左大括号 print(f"result[0]} {result[1]} {result[3]}") 但是您的主要问题是,在您的 while 循环中,first_valuefifth_value 在 while 循环针对第一个 id 运行时不断增加,但是它们永远不会重置,因此对于每个后续 id,您永远不会进入 while 循环。

    【讨论】:

    • 是的,当我复制并粘贴代码时错过了 {。您如何建议我然后重置循环
    • 如果我了解您的代码应该如何工作,只需将您的 first_valuefifth_value 初始化移动到与您的 while 语句相同的缩进级别的正上方。
    • 感谢这现在适用于前两个 ID,即打印出前两个 ID 的 14 组数据。但是在第三个 ID 的两个条目之后,我得到 ValueError: max() arg is an empty sequence
    • 如果您的列表理解返回一个空列表,因为 num_list 中没有任何内容与 i[1] &lt;= fifth_value and i[1] &gt;= first_value and i[0] == id 匹配,那么您在尝试查找空列表的最大值时会出错。
    • 那么为什么你认为它返回一个空列表但只有在控制台打印了一些输出之后
    【解决方案3】:

    我不确定你想要什么,但这是我的 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
    

    【讨论】:

    • 如果我想在 max 列之后添加另一列,平均值在同一范围内,我可以像这里一样定义它吗?
    • 当然。如果平均值是从get_max_within_time_window 中的集合entries_filtered 计算的,则可以在该函数中添加平均值的计算(并且可能将其重命名为get_max_and_average)。如果您对此有任何问题,可以在 cmets 中提问或添加新问题。
    • 我最终在这里以类似的方式定义了一个新函数 get_avg_within_time_window。我在返回部分使用了 np.mean,但在 get_avg_within_time_window return np.mean(entries_filtered_avg, key = lambda x:x[3]) TypeError: mean( ) 得到了一个意外的关键字参数 'key'
    猜你喜欢
    • 2012-08-29
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    • 2022-11-18
    • 2015-02-22
    • 1970-01-01
    • 1970-01-01
    • 2014-12-24
    相关资源
    最近更新 更多