Python 获取列表中每个元素第一次出现的索引?
我有一个大约90k个元素的列表(大约670个)。我想得到每个值第一次出现的索引。我刚刚尝试过这样的列表理解: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)
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()
方法是这样实现的,但我确信它是尽可能快的。.仅供将来参考:它似乎是这样实现的:)