2

我有两个具有相同数量元素的列表,它们都是字符串。这些字符串是相同的集合,但在每个列表中的顺序不同,没有重复。

list_a = ['s1', 's2', 's3', 's4', 's5', ...]
list_b = ['s8', 's5', 's1', 's9', 's3', ...]

我需要遍历每个元素list_a并找到list_b包含相同元素的索引。我可以用两个嵌套的 for 循环来做到这一点,但必须有更好/更有效的方法:

b_indexes = []
for elem_a in list_a:
    for indx_b, elem_b in enumerate(list_b):
        if elem_b == elem_a:
            b_indexes.append(indx_b)
            break
4

4 回答 4

4

如果没有重复,您可以使用list.index()

list_a = ['s1', 's2', 's3', 's4', 's5']
list_b = ['s8', 's5', 's1', 's9', 's3']
print [list_b.index(i) for i in list_a]

你只需要使用一个for循环,因为你已经说过list_a中的字符串也会出现在list_b中,所以不需要if elem_b == elem_a:遍历第二个列表。

于 2013-10-07T11:40:44.930 回答
3

功能风格:

map(list_b.index, list_a)

将生成一个列表,其中包含 list_a 中每个元素在 list_b 中的索引。

于 2013-10-07T11:47:51.717 回答
2

这应该为您提供索引列表。

[list_b.index(elem) for elem in list_a]
于 2013-10-07T11:41:43.753 回答
1

该方法的另一种index方法是一次构建位置字典,而不是每次都搜索列表。如果列表足够长,这应该更快,因为它使过程在元素数量(平均)上呈线性,而不是二次。具体来说,而不是

def index_method(la, lb):
    return [lb.index(i) for i in la]

你可以使用

def dict_method(la, lb):
    where = {v: i for i,v in enumerate(lb)}
    return [where[i] for i in la]

这应该在小列表上大致可比,尽管可能会慢一点:

>>> list_a = ['s{}'.format(i) for i in range(5)]
>>> list_b = list_a[:]
>>> random.shuffle(list_b)
>>> %timeit index_method(list_a, list_b)
1000000 loops, best of 3: 1.86 µs per loop
>>> %timeit dict_method(list_a, list_b)
1000000 loops, best of 3: 1.93 µs per loop

但在较长的情况下应该会快得多,而且差异只会越来越大:

>>> list_a = ['s{}'.format(i) for i in range(100)]
>>> list_b = list_a[:]
>>> random.shuffle(list_b)
>>> %timeit index_method(list_a, list_b)
10000 loops, best of 3: 140 µs per loop
>>> %timeit dict_method(list_a, list_b)
10000 loops, best of 3: 20.9 µs per loop
于 2013-10-07T12:39:54.073 回答