为什么这个基于 zip 对象的列表理解在后续的循环迭代中不起作用?

Why does this list comprehension based on zip object does not work in subsequent loop iterations?

我有一段代码,我想在连续循环迭代中过滤掉列表的一部分:

def calculate_delays(flash_time_stamps, sample_time_stamps, sample_values, threshold):
    delays = []
    first_thresh_cross_time_stamps = []
    samples = zip(sample_time_stamps, sample_values)
    # For each flash find the first sample that crosses the chosen threshold 
    # and calculate the difference between the corresponding timestamps
    for flash_time_stamp in flash_time_stamps:
        first_cross_thresh_time_stamp = -1
        # Ignore samples that occured before the flash
        samples_filtered = [s for s in samples if s[0] >= flash_time_stamp]    # ---COMPREHENSION IS HERE---
        for sample in samples_filtered:
            if sample[1] < threshold:
                first_cross_thresh_time_stamp = sample[0]
                break

        # Save
        first_thresh_cross_time_stamps.append(first_cross_thresh_time_stamp)
        delays.append(first_cross_thresh_time_stamp - flash_time_stamp)
    
    return first_thresh_cross_time_stamps, delays

在第一次迭代中,代码按预期工作,但在后续迭代中,列表理解 returns 是一个空列表。我知道根据我传递的数据不应该是这种情况。此外,以下代码按预期工作:

def calculate_delays(flash_time_stamps, sample_time_stamps, sample_values, threshold):
    delays = []
    first_thresh_cross_time_stamps = []
    samples = zip(sample_time_stamps, sample_values)
    # For each flash find the first sample that crosses the chosen threshold 
    # and calculate the difference between the corresponding timestamps
    for flash_time_stamp in flash_time_stamps:
        first_cross_thresh_time_stamp = -1
        # Ignore samples that occured before the flash
        for sample in samples:
            if sample[0] < flash_time_stamp:    # ---CHANGE HERE---
                continue
            if sample[1] < threshold:
                first_cross_thresh_time_stamp = sample[0]
                break

        # Save
        first_thresh_cross_time_stamps.append(first_cross_thresh_time_stamp)
        delays.append(first_cross_thresh_time_stamp - flash_time_stamp)
    
    return first_thresh_cross_time_stamps, delays

我做错了什么?

我什至不会在这里使用列表推导式,第二个代码片段会更有效率,因为如果第一个元素让您提前中断循环,您就不会不必要地创建列表。

您可以只使用 next 并完全替换整个 for 循环

first_cross_thresh_time_stamp = next(
    (s[0] for s in samples if s[0] >= flash_time_stamp and s[1] < threshold),
    -1
)
first_thresh_cross_time_stamps.append(first_cross_thresh_time_stamp)

当您遍历 zip 对象时,它会弹出所有数据,所以第二次这是一个空列表 samples_filtered = [s for s in samples if s[0] >= flash_time_stamp] 因此您可以像这样随时随地压缩数据:

samples_filtered = [s for s in zip(sample_time_stamps, sample_values) if s[0] >= flash_time_stamp]