提取python列表中非重复元素的索引
我有一份清单:提取python列表中非重复元素的索引,python,algorithm,search,Python,Algorithm,Search,我有一份清单: input = ['a','b','c','a','b','d','e','d','g','g'] 我想索引的所有元素,除了重复的列表 output = [0,1,2,5,6,8] 您应该迭代枚举列表,将每个元素添加到一组“已看到”元素中,如果该元素尚未看到(不在“已看到”集中),则将索引添加到输出列表中 哦,名称input覆盖了内置的input()函数,所以我将其重命名为input\u list output = [] seen = set() for i,e in enu
input = ['a','b','c','a','b','d','e','d','g','g']
我想索引的所有元素,除了重复的列表
output = [0,1,2,5,6,8]
您应该迭代枚举列表,将每个元素添加到一组“已看到”元素中,如果该元素尚未看到(不在“已看到”集中),则将索引添加到输出列表中 哦,名称
input
覆盖了内置的input()
函数,所以我将其重命名为input\u list
output = []
seen = set()
for i,e in enumerate(input_list):
if e not in seen:
output.append(i)
seen.add(e)
它将输出作为[0,1,2,5,6,8]
为什么要使用电视机?
你可能会想,既然你可以做以下事情,为什么还要用电视机呢
[i for i,e in enumerate(input_list) if input_list.index(e) == i]
这会起作用,因为.index
会返回列表中第一个元素的索引以及该值,因此如果您根据该值检查元素的索引,则可以断言它是该元素的第一次出现,并过滤掉那些不是第一次出现的元素
但是,这不如使用集合有效,因为list.index
要求Python在列表上迭代,直到找到元素(或者不找到)。这个操作是O(n)
复杂的,因为我们对input\u list
中的每个元素都调用它,所以整个解决方案将是O(n^2)
另一方面,与第一个解决方案一样,使用集合会产生一个O(n)
解决方案,因为检查一个元素是否在集合中是复杂的O(1)
(平均情况)。这是由于集合是如何实现的(它们类似于列表,但每个元素都存储在其散列的索引中,因此您可以只计算元素的散列,并查看是否有元素用于检查成员资格,而不是对其进行迭代-请注意,这是一种模糊的过度简化,但这正是它们的想法)
因此,由于每个成员资格检查都是O(1)
,并且我们对每个元素都执行此操作,因此我们得到了一个O(n)
解决方案,它比O(n^2)
解决方案要好得多。您可以执行类似的操作,检查计数(尽管计算量很大):
这将检查以下各项:
如果项目仅出现一次。如果是,请继续
如果到目前为止该项目还没有出现在列表中。如果是,请添加到结果列表中
如果您不介意索引最后出现的重复项,而是使用Python 3.6+,那么这里有一个替代解决方案:
list(dict(map(reversed, enumerate(input))).values())
这将返回:
[3, 4, 2, 7, 6, 9]
这是一个使用zip
和reversed
>>> input = ['a','b','c','a','b','d','e','d','g','g']
>>> sorted(dict(zip(reversed(input), range(len(input)-1, -1, -1))).values())
[0, 1, 2, 5, 6, 8]
此问题缺少pandas
解决方案 还有一个版本,在列表理解中使用了副作用
>>> xs=['a','b','c','a','b','d','e','d','g','g']
>>> seen = set()
>>> [i for i, v in enumerate(xs) if v not in seen and not seen.add(v)]
[0, 1, 2, 5, 6, 8]
列表将筛选尚未看到的值的索引。
诀窍是看不见。添加(v)
总是正确的,因为看到了。添加(v)
返回无
。
由于短路评估的原因,seen.add(v)
在且仅当v
未在seen中时执行,并动态向seen
添加新值
最后,seen包含输入列表的所有值
>>> seen
{'a', 'c', 'g', 'b', 'd', 'e'}
注意:在列表理解中使用副作用通常不是一个好主意,
但有时您可能会看到此技巧。欢迎使用stackoverflow!请拿起这本书,仔细阅读,并提供一份能再现您的问题的报告。你试过什么?您在哪里遇到问题?这将给出唯一元素的索引,而不是问题中要求的元素出现的第一个索引。
>>> seen
{'a', 'c', 'g', 'b', 'd', 'e'}