根据元组值合并两个元组列表

时间:2013-08-29 08:03:47

标签: python list tuples

我有两个列表ref_listdata_list包含每个元组,第一个元素就像第二个时间,第二个元素是随机值:

ref_list = [(1,value_ref_1),(3,value_ref_3),(4,value_ref_4), ... ]
data_list = [(1,value_dat_1),(2,value_dat_2),(4,value_dat_4), ... ]

我想计算第二个值与时间(元组的第一个值)的函数的差异。这意味着,元组列表的第一个值是时间,第二个值是第二个值的差值。我希望它能够使用上次管理两个列表中的任何一个中的缺失数据! 对于前面的示例,结果将是:

res_list = [(1,value_dat_1-value_ref_1),(2,value_dat_2-value_ref_1),(3,value_dat_2-value_ref_3),(4,value_dat_4-value_ref_4), ... ]

在此示例中,元组(2,value_dat_2-value_ref_1)是使用元组(2,value_dat_2)(1,value_ref_1)创建的,因为2中缺少ref_list作为第一个元组的元组。同样的想法反过来(3,value_dat_2-value_ref_3)

我无法弄清楚如何使用列表理解来实现它。

我希望我足够清楚。

非常感谢。

2 个答案:

答案 0 :(得分:1)

编辑1: IndexError:如果两个列表具有相同的长度,则不应该有索引错误。 data_list [i]将给出data_list的第i个元素,而不管其内容如何。 当你从python list()中弹出一个值时,它会'移动'索引,所以你没有索引间隙(与其他语言不同)。或者也许我不太了解你的担忧。

缺少数据:是的,是的。 因此,如果缺少值,则需要返回多个值:上限和下限

[(elt[0],data_list[i][1]-elt[1]) if data_list[i][0]==elt[0] else ((elt[0],data_list[i][1]-ref_list[i-1][1]),(elt[0],data_list[i][1]-ref_list[i+1][1])) for i,elt in enumerate(ref_list)]

这样,如果缺少一个值,它将搜索前一个值和下一个值,因此您可以获得缺失值的边界。我没有其他选择,只能返回另一个结构中的'else'元组,因为我每回合只能返回一个'值'。 (或者在'for'面临SyntaxError:无效语法)

即使您可能需要这些元组元组(以检测缺少值),您可能想知道另一个解决方案 - 显式生成器。

def generator_stuff(data_list,ref_list):
    for i,elt in enumerate(ref_list):
        if data_list[i][0]==elt[0]:
            yield (elt[0],data_list[i][1]-elt[1])
        else:
            yield (elt[0],data_list[i][1]-ref_list[i-1][1])
            yield (elt[0],data_list[i][1]-ref_list[i+1][1])

我完全不知道它的性能,但是当它单独返回每个元组时,你将不会有元组元组。

答案 1 :(得分:1)

另外还有两个列表,每个列表500k值,100mb / 200mb(取决于生成参数)稳定的内存使用

list_a = [(1,222),(2,444),(5,666),(10,888)]
list_b = [(1,111),(3,333),(7,555),(9,777),(10,888)]

list_c = []

i = 1
a = None
b = None


def get_new(a, for_time):
    if len(a) == 0:
        raise IndexError

    # in the future
    if a[0][0] > for_time:
        return None

    return a.pop(0)

list_a_exhausted = False
list_b_exhausted = False

while True:     
    try:
        a = get_new(list_a,i) or a
    except IndexError:
        list_a_exhausted = True

    try:
        b = get_new(list_b,i) or b  
    except IndexError:
        list_b_exhausted = True

    if list_a_exhausted and list_b_exhausted:
        break

    list_c.append([(i,b[1]-a[1])])  
    i = i + 1