Python 获取列表中每个元素第一次出现的索引?

Python 获取列表中每个元素第一次出现的索引?,python,list-comprehension,Python,List Comprehension,我有一个大约90k个元素的列表(大约670个)。我想得到每个值第一次出现的索引。我刚刚尝试过这样的列表理解: In: [["foo", "bar", "baz", "bar", "foo"].index(x) for x in ["foo", "bar", "baz", "bar", "foo"]] Out: [0, 1, 2, 1, 0] my_list = ["foo", "bar", "baz", "bar", "foo"] my_list_unique = set(my_list)

我有一个大约90k个元素的列表(大约670个)。我想得到每个值第一次出现的索引。我刚刚尝试过这样的列表理解:

In: [["foo", "bar", "baz", "bar", "foo"].index(x) for x in ["foo", "bar", "baz", "bar", "foo"]]
Out: [0, 1, 2, 1, 0]
my_list = ["foo", "bar", "baz", "bar", "foo"]

my_list_unique = set(my_list)
indexes = [(x, my_list.index(x)) for x in my_list_unique]
print(indexes)  # prints -> [('foo', 0), ('bar', 1), ('baz', 2)]

这是可行的,但在我的机器上运行需要几分钟。有什么更好(更快)的方法可以做到这一点?

我认为您只需要使用
枚举
(除非您希望列表中的每个项目第一次出现):

输出

0 foo
1 bar
2 baz
3 bar
4 foo
例如,如果希望使用
1条
而不是
3条
,则可以维护找到的字符串的字典:

for index, value in enumerate(strings):
    if value not in d:
        d[value] = index

for value in strings:
    print value, d[value]

你的问题很模糊,但据我所知,你有许多重复的值,你只想得到每个值的第一次出现的索引。我会利用这样的集合:

In: [["foo", "bar", "baz", "bar", "foo"].index(x) for x in ["foo", "bar", "baz", "bar", "foo"]]
Out: [0, 1, 2, 1, 0]
my_list = ["foo", "bar", "baz", "bar", "foo"]

my_list_unique = set(my_list)
indexes = [(x, my_list.index(x)) for x in my_list_unique]
print(indexes)  # prints -> [('foo', 0), ('bar', 1), ('baz', 2)]

请注意,在第3行中创建集合会删除重复项,因此
my_list_unique
中的每个条目只存在一次。这节省了查找索引的时间。就结果而言,它是一个元组列表,其中每个元组都包含字符串和索引,在
my_list

中首先找到该字符串和索引。您可以构建一个字典,存储每个单词第一次出现的索引。 这样,您只需查看一次大列表,而字典的查找速度要快得多,因为字典只包含每个值一次,并且在O(log(n))中访问

此外,如果要输出一个90k长的列表,其中包含原始列表中每个元素第一次出现的索引,可以通过以下方式获得:

output = [v[x] for x in l]
# output is now [0, 1, 2, 1, 0]

您想列举列表中的项目吗?如果是这样,请使用
枚举([“foo”、“bar”、“baz”、“bar”、“foo”])
。我不想枚举列表,我只是想得到第一次出现的索引。我要解决我的问题。你希望输出是
[0,1,2,1,0]
还是没有重复项?我希望输出是
[0,1,2,1,0]
@NathanMiller在这种情况下,我认为你目前的方法可能是最快的方法。几分钟的等待似乎没有那么长。@Chris_Rands,我确实希望第一次出现(我的问题/标题之前写得不好),这对于OP发布的示例很好,但对于包含90k元素和600个唯一值的列表来说效果并不好。@Ev.Kounis有些事情需要时间。在比较散列值以识别集合中的重复项方面,您没有什么可以改进的。第4行中的列表理解不会让您在90k长的列表中迭代670次吗?大列表是90k长的,第4行中的列表理解会迭代
my_list_unique
,这只是670项。是的,但是
my_list.index()
还必须遍历
my_list
。。。仅在当前
x
第一次出现之前,但它仍然是不可忽略的。@maahl我怀疑
index()
方法是这样实现的,但我确信它是尽可能快的。.仅供将来参考:它似乎是这样实现的:)