a = [3, 4, 2, 1, 7, 6, 5]
b = [4, 6]
答案应该是1,因为在4首先出现在列表B,它的指数是1如何查找首先出现在另一个给定列表中的列表中元素的索引?
的问题是,有没有在Python任何快的代码来实现这一目标?
PS:其实一个是随机排列和b是的一个子集,但它表示为列表。
a = [3, 4, 2, 1, 7, 6, 5]
b = [4, 6]
答案应该是1,因为在4首先出现在列表B,它的指数是1如何查找首先出现在另一个给定列表中的列表中元素的索引?
的问题是,有没有在Python任何快的代码来实现这一目标?
PS:其实一个是随机排列和b是的一个子集,但它表示为列表。
b
如果是被视为一个子集(顺序无关紧要,所有值都存在于a
),然后使用min()
用map()
:
min(map(a.index, b))
这返回最低索引。这是一个O(NK)溶液(其中N是a
,K那的b
的长度),但所有的循环是用C代码执行。
另一种选择是a
转换为一组,并在循环中使用next()
超过enumerate()
:
bset = set(b)
next(i for i, v in enumerate(a) if v in bset)
这是O(N)的解决方案,但具有较高的恒定成本(Python的字节码来执行)。这在很大程度上取决于哪一个将是更快的a
和b
大小。
对于在问题,min(map(...))
胜小输入例如:
In [86]: a = [3, 4, 2, 1, 7, 6, 5]
...: b = [4, 6]
...:
In [87]: %timeit min(map(a.index, b))
...:
608 ns ± 64.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [88]: bset = set(b)
...:
In [89]: %timeit next(i for i, v in enumerate(a) if v in bset)
...:
717 ns ± 30.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
在一个行:
print("".join([str(index) for item in b for index,item1 in enumerate(a) if item==item1][:1]))
输出:
1
详细地:
a = [3, 4, 2, 1, 7, 6, 5]
b = [4, 6]
new=[]
for item in b:
for index,item1 in enumerate(a):
if item==item1:
new.append(index)
print("".join([str(x) for x in new[:1]]))
这不会产生* first *索引。 –
@MartijnPieters,纠正它,谢谢。 –
这仍然没有给你最低的指数。如果'a = [6,4]'你会得到错误的答案。 –
对于小B样本,集合方法依赖于输出,执行时间随着索引输出线性增长。在这种情况下,Numpy可以提供更好的解决方案。
N=10**6
A=np.unique(np.random.randint(0,N,N))
np.random.shuffle(A)
B=A[:3].copy()
np.random.shuffle(A)
def find(A,B):
pos=np.in1d(A,B).nonzero()[0]
return pos[A[pos].argsort()][B.argsort().argsort()].min()
def findset(A,B):
bset = set(B)
return next(i for i, v in enumerate(A) if v in bset)
#In [29]: find(A,B)==findset(A,B)
#Out[29]: True
#In [30]: %timeit findset(A,B)
# 63.5 ms ± 1.31 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
#
# In [31]: %timeit find(A,B)
# 2.24 ms ± 52.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
所以对于'b = [6,4]',答案应该是一样的吗?你有没有尝试过自己呢? –
“b”总是一个子集,或者'b'中的值不在'a'中? –
所以,你基本上想'a.index(b [0])'? –