【发布时间】:2020-09-10 15:47:02
【问题描述】:
我有两个元组列表,我想根据条件将e 中的元素映射到s 中的元素。条件是e 中某物的第一个元素需要>= 到s 中的第一个元素,e 中的元素1+2 需要s 中的元素1+2。每个s 元组中的第一个数字是起始位置,第二个是长度。我可以这样做:
e = [('e1',3,3),('e2',6,2),('e3',330,3)]
s = [('s1',0,10),('s2',11,24),('s3',35,35),('s4',320,29)]
for i in e:
d = {i:j for j in s if i[1]>=j[1] and i[1]+i[2]<=j[1]+j[2]}
print(d)
输出(我想要的):
{('e1', 3, 3): ('s1', 0, 10)}
{('e2', 6, 2): ('s1', 0, 10)}
{('e3', 330, 3): ('s4', 320, 29)}
有没有更有效的方法来获得这个结果,理想情况下没有 for 循环(至少不是双循环)?我已经用zip 尝试了一些东西,以及一些类似的东西
list(map(lambda i,j: {i:j} if i[1]>=j[1] and i[1]+i[2]<=j[1]+j[2] else None, e, s))
但它并没有给我我想要的东西。
s 中的元素永远不会重叠。例如,您不会有 ('s1',0,10) 和 ('s2', 5,15)。换句话说,范围 (0, 0+10) 永远不会与 (5,5+15) 或任何其他元组的范围重叠。此外,e 中的所有元组都是唯一的。
【问题讨论】:
-
在最坏的情况下,你不能比双重嵌套循环做得更好(假设
e中的每个元素都是('ex', 1, 0),s中的每个元素都是('sx', 0, 2))。您是否有任何额外的限制,以便我们平均可以做得更好?例如,与所有可能结果的空间相比,结果集是否稀疏? -
@FMc 谢天谢地,这实际上并非如此。他们指定的约束在某种意义上是关联的,可以让你避免很多额外的比较。在最坏的情况下,您可能仍然有 2 个循环的输出,我认为对于大多数输入,我们可以做得更好。
-
@HansMusgrave 他们唯一的约束是列出的。这是否意味着我所拥有的和它所能得到的一样好?
-
@formicaman 有点像。现在您的解决方案需要
len(e) * len(s)时间,即使len(results) == 0也是如此。我正在研究一个运行时间略高于len(results) + len(e) + len(s)的答案,这对于大多数输入来说会更快。如果你没有额外的限制,那么仍然会有一些输入会导致这个想法变慢,但它们不应该经常出现。 -
@HansMusgrave 谢谢。是的,唯一的事情是从 i[1] 到 i[2] 的范围需要在 s[1] 到 s[2] 之内——如果要创建该映射。
标签: python list dictionary