我有两个列表具有相同数量的元素,所有这些都是字符串。这些字符串是相同的集合,但在每个列表中的顺序不同,没有重复。
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
答案 0 :(得分: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:
并遍历第二个列表。
答案 1 :(得分:3)
功能风格:
map(list_b.index, list_a)
将生成一个列表,其中包含list_a中每个元素的list_b中的索引。
答案 2 :(得分:2)
这应该会给你一个索引列表。
[list_b.index(elem) for elem in list_a]
答案 3 :(得分: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