Python 比较两个不同的列表
我有两个不同长度的列表。示例-- 及Python 比较两个不同的列表,python,list,Python,List,我有两个不同长度的列表。示例-- 及 (当然E2的元素数比E1多)。现在我想比较E1列表和E2,找出最接近E1中每个元素的值,比如在本例中E1中的1.3最接近E2中的1.1699。类似地,我想对E1中的所有其他元素执行此操作。。。因此,如果我在E2中形成一个新的列表E3,它将包含与E1完全相似的元素数量和最接近E1元素的值。我该怎么做?感谢您的帮助。快速脏版: E3 = [min(E2, key=lambda x: abs(x-i)) for i in E1] 对于E1中的每个元素,它根据与E
(当然E2的元素数比E1多)。现在我想比较E1列表和E2,找出最接近E1中每个元素的值,比如在本例中E1中的1.3最接近E2中的1.1699。类似地,我想对E1中的所有其他元素执行此操作。。。因此,如果我在E2中形成一个新的列表E3,它将包含与E1完全相似的元素数量和最接近E1元素的值。我该怎么做?感谢您的帮助。快速脏版:
E3 = [min(E2, key=lambda x: abs(x-i)) for i in E1]
对于E1
中的每个元素,它根据与E1
元素的绝对距离查找E2
的最小元素
请注意,此列表将包含重复项。例如,对于您的示例,它返回:
[1.0, 1.1699, 1.1699, 1.1699, 1.1699]
因为1.1699最接近E1
中的所有较大值
线性时间,但更复杂的排序列表解决方案:
E3 = []
p2 = 0
for e1 in E1:
while p2 < len(E2) - 1 and abs(E2[p2] - e1) > abs(E2[p2+1] - e1):
p2 += 1
E3.append(E2[p2])
E3=[]
p2=0
对于e1中的e1:
而p2abs(E2[p2+1]-e1):
p2+=1
E3.追加(E2[p2])
让我向您介绍一个最奇妙的Python模块,对分
import bisect
def find_nearest(refsort, pt):
loc = bisect.bisect_left(refsort, pt)
if loc >= len(refsort)-1:
# Value greater than all elements of refsort
return refsort[-1]
d1 = pt - refsort[i]
d2 = refsort[i+1] - pt
if d1 < d2:
return refsort[i]
else:
return refsort[i+1]
def replace_with_nearest(ptlist, reflist):
''' Replace every point in ptlist with the nearest value from reflist '''
refsort = sorted(reflist) # omit if you know reflist is sorted
return [find_nearest(refsort, pt) for pt in ptlist]
E3 = replace_with_nearest(E1, E2)
导入对分
def find_最近(参考排序,pt):
loc=对分。左对分(参考排序,pt)
如果loc>=len(参考排序)-1:
#值大于refsort的所有元素
返回refsort[-1]
d1=pt-refsort[i]
d2=参考排序[i+1]-pt
如果d1
bisect
使用经典的数组对分技术,在O(logn)
时间中查找小于给定输入的最大数组元素,假设数组已排序。我们使用它来定位两个值,这两个值比E2
的每个元素都要小和大
这在O(n log k)时间内运行,其中n
是E2的长度,k
是E1的长度(假设n>k)。请注意,E2不需要排序。def最近(num,lst):
def closest(num, lst):
ret = lst[0]
dist = abs(lst[0]-num)
for n in lst:
if abs(n-num) < dist:
dist = abs(n-num)
ret = n
return ret
e1 = [1.0,1.3,1.69,2.1970,2.8561]
e2 = [1.00,1.04,1.08,1.1249,1.1699]
e3 = [closest(n, e2) for n in e1]
print(e3)
ret=lst[0]
dist=abs(lst[0]-num)
对于lst中的n:
如果abs(n-num)
[1.0, 1.1699, 1.1699, 1.1699, 1.1699]
你说的最接近是指差异最小的地方?列表是否已排序?这确实会受益于两个输入的精确样本和所需输出的精确样本。有助于清除您定义为“最接近”的内容。@Burhan Khalid列表已排序。最接近意味着差异最小。这比使用
sorted
而不是min
的版本要好,但仍然比解决问题所需的速度慢得多。如果对输入进行排序,我们可以在线性时间内通过对输入进行单次传递来解决问题。如果输入未排序,我们可以在线性时间内对其排序,然后应用相同的算法。@user2357112,是的,这不是特别有效。为排序列表添加了线性时间版本。谢谢!但是用字典而不是列表会发生什么呢?key=lambda也可以在字典中使用吗?如果可能的话,如何使用?@user3724647,使用dict,您可以根据数字的不同选择“keys()”或values()
,并使用该列表。这在O(n*m)时间(二次型)内运行,速度不是特别快。@nneonno,没有参数。如果性能是关键,你的答案就是我想要的。我想你可能把E1
和E2
搞混了。是的,是的。让我来解决这个问题。
import bisect
def find_nearest(refsort, pt):
loc = bisect.bisect_left(refsort, pt)
if loc >= len(refsort)-1:
# Value greater than all elements of refsort
return refsort[-1]
d1 = pt - refsort[i]
d2 = refsort[i+1] - pt
if d1 < d2:
return refsort[i]
else:
return refsort[i+1]
def replace_with_nearest(ptlist, reflist):
''' Replace every point in ptlist with the nearest value from reflist '''
refsort = sorted(reflist) # omit if you know reflist is sorted
return [find_nearest(refsort, pt) for pt in ptlist]
E3 = replace_with_nearest(E1, E2)
def closest(num, lst):
ret = lst[0]
dist = abs(lst[0]-num)
for n in lst:
if abs(n-num) < dist:
dist = abs(n-num)
ret = n
return ret
e1 = [1.0,1.3,1.69,2.1970,2.8561]
e2 = [1.00,1.04,1.08,1.1249,1.1699]
e3 = [closest(n, e2) for n in e1]
print(e3)
[1.0, 1.1699, 1.1699, 1.1699, 1.1699]