我有一个非常长的lst
包含唯一元素。我想设计一个函数,它将元素列表作为输入,它可以有效地返回索引列表。我们假设找到索引所需的项目都在lst
。
以下是一个例子:
lst = ['ab','sd','ef','de']
items_to_find = ['sd', 'ef', 'sd']
>>> fo(lst, items_to_find)
# Output: [1,2,1]
我有一个属于自己的解决方案,但看起来效率不高。
>> [lst.index(x) for x in items_to_find]
因为lst
很长,我需要一个非常快速的算法来解决它。
答案 0 :(得分:6)
首先创建一个包含列表中每个项目的索引位置的字典(您声明所有项目都是唯一的,因此重复键没有问题。)
然后使用字典查找每个项目的索引位置,即平均时间复杂度O(1)。
&sslverifycertificate=false
答案 1 :(得分:2)
您可以使用包含来自lst的元素的字典作为键和索引以及值。在字典中搜索是O(1)。
答案 2 :(得分:0)
虽然您接受的答案非常好,但这里的内存效率更高,而且可能几乎一样快。但是@ Alexander的answer如果列表很长(因为其中的元素都是唯一的),就会创建一个可能很大的字典。
下面的代码还构建了一个字典来加速搜索,但它是针对目标元素的,因此可能比搜索列表小得多。对于示例数据,它创建的数据(名为targets
)仅包含:{'sd': [0, 2], 'ef': [1]}
它通过序列并检查其中的每个值是目标,如果是,则根据更新结果列表。这种方法需要更多的代码才能实现,因为设置稍微复杂一些,所以这是另一种权衡。
def find_indices(seq, elements):
targets = {}
for index, element in enumerate(elements):
targets.setdefault(element, []).append(index)
indices = [None for _ in elements] # Pre-allocate.
for location, value in enumerate(seq):
if value in targets:
for element, indexes in targets.items():
if element == value:
for index in indexes:
indices[index] = location
return indices
lst = ['ab', 'sd', 'ef', 'de']
indices = find_indices(lst, ['sd', 'ef', 'sd'])
print(indices) # -> [1, 2, 1]
答案 3 :(得分:0)
简单的第一近似......
def get_indices(data_list, query_list):
datum_index_mapping = {datum:None for datum in query_list}
for index, datum in enumerate(data_list):
if datum in datum_index_mapping:
datum_index_mapping[datum] = index
return [datum_index_mapping[d] for d in query_list]
以上是最简单,最直观的解决方案,它可以提高效率(只需要为实际想要查找的元素存储索引字典)。
然而,它受到这样的事实 - 即使初始查询列表非常短 - 它将遍历整个数据列表/数据生成器。此外,它必须在每次看到之前看到的值时写入字典。下面修复了那些效率低下的问题,虽然它增加了集合的开销,因此它必须为查询列表中的每个唯一元素执行集合写入,以及为查询列表中的每个唯一元素写入字典。
def get_indices(data_list, query_list):
not_found = set(query_list)
datum_index_mapping = {}
for index, datum in enumerate(data_list):
if datum in not_found:
datum_index_mapping[datum] = index
not_found.remove(datum)
if len(not_found) == 0:
break
return [datum_index_mapping[d] for d in query_list]
显然,根据您的程序,您可能根本不想拥有索引列表,只需让您的函数返回映射。
如果您要解析多个任意查询列表,您可能只想在其他答案显示的原始数据集上执行enumerate()
,并保留将值映射到内存中的索引以及查询目的的字典。 / p>
有效率往往取决于更大的计划;我们所能做的就是进行优化。它还取决于内存层次结构和处理能力(即我们可以并行化吗?计算更昂贵,还是内存更昂贵?如果我们需要回退交换,I / O会是什么?)。
答案 4 :(得分:0)
如果您确定所有搜索到的值实际上都存在于搜索列表中并且对lst进行了排序(当然,排序本身可能需要一些时间),则可以一次性完成(线性复杂度):
def sortedindex(lst,find):
find.sort()
indices = []
start = 0
for item in find:
start = lst.index(item,start)
indices.append(start)
return indices
“开始”显示第一个索引,算法从该索引开始将检查的项目与主列表中的项目进行比较。找到正确的索引后,它将成为下一个起始标记。因为两个列表都以相同的方式排序,所以您不必担心会跳过下一个项目。