我的列表列表存在问题。
假设我有以下信息:
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)
答案 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']