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

时间:2016-11-16 17:02:21

标签: 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]

这样可行,但在我的机器上运行需要几分钟。有什么更好(更快)的方法呢?

3 个答案:

答案 0 :(得分:2)

我想您只想使用enumerate(除非您希望列表中每个项目首次出现):

strings = ["foo", "bar", "baz", "bar", "foo"]
for index, value in enumerate(strings):
    print index, value

输出

0 foo
1 bar
2 baz
3 bar
4 foo

如果您需要,例如1 bar而不是3 bar,则可以维护已找到字符串的字典:

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

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

答案 1 :(得分:2)

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

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中找到它的索引

答案 2 :(得分:2)

您可以构建一个字典来存储每个单词第一次出现的索引。 这样,您只需查看一次大列表,并且字典查找速度更快,因为字典仅包含每个值一次,并且可以在O(log(n))中访问。

l = ["foo", "bar", "baz", "bar", "foo"]
v = {}
for i, x in enumerate(l):
    if x not in v:
        v[x] = i

# v is now {'bar': 1, 'baz': 2, 'foo': 0}

此外,如果要输出一个90k长的列表,其中包含原始列表中每个元素的第一个匹配项的索引,您可以这样做:

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