Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
提取python列表中非重复元素的索引_Python_Algorithm_Search - Fatal编程技术网

提取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'}