我正在寻找一个有效的函数,在距离为k的列表中找到相等的元素。
输入示例:
v=['a','c','d','e','a','c','e','e','e','d']
k=4
期望产出:
['a', 'c', 'e']
原因:a同时位于0和4 4-0=k,c同时位于1和5-1=k,e同时位于3和7-3=k。
如果可能的话,我正在寻找比用for循环逐个元素循环更有效的东西。也就是说,我在寻找比以下更好的东西:
def dist_k(k, v):
v_len = len(v)
out = []
for i in range(0,v_len,1):
if i+k < v_len:
if v[i] == v[i+k]:
out.append(v[i])
print(out)
发布于 2022-04-28 08:32:04
编辑
我找到了一种聪明的方法,可以更快地做到这一点,而不需要np.roll
,而且不会将数组视为循环:
>>> import numpy as np
>>> v = ['a','c','d','e','a','c','e','e','e','d']
>>> v_np = np.array(v)
>>> k = 4
>>> v_init = v_np[:-k]
>>> v_init[v_init == v_np[k:]]
array(['a', 'c', 'e'])
这样做的想法是,在没有最后一个k
元素的情况下存储数组的起始(因为在它们之后有比k
元素更少的元素)。我存储数组,因为我需要它两次。
>>> v_init = v_np[:-k]
>>> v_init
array(['a', 'c', 'd', 'e', 'a', 'c'])
然后,我使用数组的第二部分,没有第一个k
元素:
>>> v_np[k:]
array(['a', 'c', 'e', 'e', 'e', 'd'])
然后我可以比较这两个数组:
>>> v_init == v_np[k:]
array([ True, True, False, True, False, False])
最后,我可以从v_init
(而不是从v
)获得与索引对应的元素(因为数组的长度不匹配):
>>> v_init[v_init == v_np[k:]]
array(['a', 'c', 'e'])
由于Performances使用numpy (它使用C进行计算),这个方法在使用大数组时要快得多。但是,由于向numpy数组的转换,对于小列表(甚至不确定,请用您的问题尝试一下),它可能会慢一些:
def list_comprehension(v, k):
return [v[i] for i in range(len(v)-k) if v[i] == v[i+k]]
def using_numpy(v, k):
v_np = np.array(v)
v_init = v[:-k]
return v_init[v_init == v[k:]]
>>> from timeit import timeit
>>> v = np.random.rand(100000).tolist() # I consider that the input is a simple list
>>> timeit(lambda: list_comprehension(v,k), number=1000)
7.875344538999343
>>> timeit(lambda: using_numpy(v,k), number=1000)
3.646597085000394
圆周数组的原始答案
import numpy as np
v = np.array(['a','c','d','e','a','c','e','e','e','d'])
k = 4
v[v == np.roll(v,-k)]
基本上,np.roll
通过k
元素移动数组,然后将初始数组与移位数组进行比较,并保留它们相等的元素:
>>> np.roll(v, -k)
array(['a', 'c', 'e', 'e', 'e', 'd', 'a', 'c', 'd', 'e'])
>>> v == np.roll(v,-k)
array([ True, True, False, True, False, False, False, False, False,
False])
>>> v[v == np.roll(v,-k)]
array(['a', 'c', 'e'])
请注意,此方法将考虑数组是循环的,即它将数组的第一个和最后一个值视为相邻的:
>>> v=np.array(['a','c','d','e','a','c','e','e','e','d', 'a'])
>>> v[v == np.roll(v,-k)]
array(['a', 'c', 'e', 'd'])
发布于 2022-04-28 08:34:30
您可以尝试以下代码:
v=['a','c','d','e','a','c','e','e','e','d']
k=4
result = [v[i] for i in range(len(v)-k) if v[i] == v[i+k] ]
发布于 2022-04-28 09:06:24
我不知道这是否比其他建议更有效,但这是另一种选择:
v = ['a', 'c', 'd', 'e', 'a', 'c', 'e', 'e', 'e', 'd']
k = 4
print([e for e, f in zip(v, v[k:]) if e == f])
输出:
['a', 'c', 'e']
https://stackoverflow.com/questions/72040347
复制相似问题