在python中的列表列表中插入值

时间:2017-09-11 12:37:26

标签: python list nested-lists

我的列表列表存在问题。

假设我有以下信息:

path = [['B', 'C', 'A', 'A', 'B'],['C', 'B'], 'A']
index = [0, 3, 5, 6, 8, 9, 11, 14]

此数据表示在时间索引= 0时,我的观察结果为B.在时间索引= 3时,我的观察结果为C,依此类推。应该注意的是,我想将数据结构保持为列表列表,因为这意味着我在整个时间内有3个不同的观察值= 0直到时间= 14.第一个观察是从时间0到时间9,等等。

我实际上要做的是完成列表清单。意思是,我想在列表(路径)列表中添加我的观察。对于所有缺失的时间(索引处不存在1,2,4,7 ...),我想将该特定观察添加到我的列表(路径)列表中。该观察结果与先前的观察相似。因此,在时间t = 1,我的观察将是B(在时间= 0时的观察)。在时间= 2时,我的观察结果是B(观察时间= 1),依此类推。

我希望从中得到的最终结果是:

complete_path = [['B', 'B', 'B', 'C', 'C', 'A', 'A', 'A', 'B'], ['C', 'C', 'B', 'B','B'],'A']

我想我可以解决这个问题,如果它是一个列表,但我觉得列表列表很难。非常感谢您的帮助。祝你有愉快的一天!

编辑:

此问题还有两个条件: 1.有时,path可能是常规列表,而不是嵌套列表。因此,我们需要注意这种可能性。 2.如果最后一次观察只是一个值,它将导致一个字符串而不是列表。除此之外,path将始终是嵌套列表。

以下是我创建的工作代码。它看起来非常混乱,我希望任何人都能够启发我是否有可能以更好的方式解决这个问题/更少的代码行。

def complete_list(list_, index, max_index = None):
    if max_index == None:
        max_index = max(index)
    complete_list = [None]*((max_index + 1) - min(index))
    complete_list[0] = list_.pop(0)
    for true_index in range(min(index) + 1, max_index + 1):
        if true_index in index:
            complete_list[true_index - min(index)] = list_.pop(0)
        else:
            complete_list[true_index - min(index)] = complete_list[true_index - min(index) - 1]
    return complete_list

def is_lists_of_list(lists):
    return np.any([isinstance(y, list) for y in lists])

def get_first_index(lists_of_list):
    list_first_index = [0]*len(lists_of_list)
    for i in range(1,len(lists_of_list)):
        if isinstance(lists_of_list, list):
            list_first_index[i] = len(lists_of_list[i-1]) + list_first_index[i-1]
    return list_first_index

def complete_lists_of_list(lists_of_list, index, max_index):
    result = []
    n_lists = len(lists_of_list)
    list_first_index = [index[x] for x in get_first_index(lists_of_list)]
    for i in range(n_lists - 1):
        used_index = [ x for x in index if (x >= list_first_index[i]) and (x < list_first_index[i+1])]
        tmp_result = complete_list(list(lists_of_list[i]), used_index, max_index=list_first_index[i+1] - 1)
        result.append(tmp_result)
    if isinstance(lists_of_list[-1],list):
        used_index = [x for x in index if x >= list_first_index[n_lists] and x <= max_index]
        tmp_result = complete_list(list(lists_of_list[n_lists]), used_index)
        result.append(tmp_result)
    else:
        tmp_result = [lists_of_list[-1]] * (max_index - index[-1] + 1)
        result.append(tmp_result)
    return result

def smoothen_path(object, index, max_index):
    if is_lists_of_list(object):
        return complete_lists_of_list(object, index, max_index)
    else:
        return complete_list(object, index, max_index)

1 个答案:

答案 0 :(得分:1)

你可以定义一个递归函数,从迭代器中重复当前元素的频率,并将相同的迭代器传递给用于嵌套列表的递归调用。

def repeat(path, repeats):
    return [x for y in path for x in 
            ([repeat(y, repeats)] if isinstance(y, list) else [y] * next(repeats))]

要创建repeats迭代器,您可以使用zip来获取index中的连续元素对,但是您需要添加另一个元素重复最后一个元素的频率(即结果列表及其子列表的总长度。)

path = [['B', 'C', 'A', 'A', 'B'],['C', 'B'], 'A']
index = [0, 3, 5, 6, 8, 9, 11, 14]

index += [16] # end of list
repeats = (b-a for (a,b) in zip(index, index[1:]))

res = repeat(path, repeats)

对于此示例,res将为[['B', 'B', 'B', 'C', 'C', 'A', 'A', 'A', 'B'], ['C', 'C', 'B', 'B', 'B'], 'A', 'A']