以特定顺序生成元组列表

时间:2018-03-05 11:30:06

标签: python list

所以这是我的问题。我有2个频率,我生成一个附近的元组列表。

f1 = 20
f2 = 50
f = [(a, b) for a in range(f1-3, f1+4) for b in range(f2-3, f2+4)]

输出:

[(17, 47), (17, 48), (17, 49), (17, 50), (17, 51), (17, 52), (17, 53), (18, 47), (18, 48), (18, 49), (18, 50), (18, 51), (18, 52), (18, 53), (19, 47), (19, 48), (19, 49), (19, 50), (19, 51), (19, 52), (19, 53), (20, 47), (20, 48), (20, 49), (20, 50), (20, 51), (20, 52), (20, 53), (21, 47), (21, 48), (21, 49), (21, 50), (21, 51), (21, 52), (21, 53), (22, 47), (22, 48), (22, 49), (22, 50), (22, 51), (22, 52), (22, 53), (23, 47), (23, 48), (23, 49), (23, 50), (23, 51), (23, 52), (23, 53)]

现在我按它与f1和f2的距离来命令它。通过上面的例子:

[(20, 50), (19, 50), (20, 49), (21, 50), (20, 51), (21, 51), ..., (15, 45), (25, 55)]

lambda函数可以完成这项工作:

sorted(f, key=lambda x: abs(f1-x[0]) + abs(f2-x[1])) 

输出:

[(20, 50), (19, 50), (20, 49), (20, 51), (21, 50), (18, 50), (19, 49), (19, 51), ...]

问题1:如何修改lambda函数以获取(18,50)之前的值(21,51)(每个频率上的距离1优于距离2在一个频率上)?

问题2:对列表进行排序非常耗时(这里只有49个elts列表,但实际上,它可能有数千个元组)。有没有办法直接生成最终列表,从而跳过排序步骤?

编辑:问题2的澄清 我想直接生成最终列表。我能想到的唯一解决方案有点沉重: 而不是:

f = [(a, b) for a in range(f1-3, f1+4) for b in range(f2-3, f2+4)]

使用:

f = [(f1, f2)] + [(a, b) for a in range(f1, f1+2) for b in range(f2, f2+2)] + [(a, b) for a in range(f1, f1-2, -1) for b in range(f2, f2-2, -1)] + ... Distance of 2 + Distance of 3 + so on

除了重线之外,我创建了可以通过list(set(f))消除的重复项,但后来我因为没有排序而失去了时间......

感谢。

3 个答案:

答案 0 :(得分:3)

关于问题1,您可以使用几何距离测量:

import math
...
sorted(f, key=lambda x: math.sqrt(pow(f1-x[0],2) + pow(f2-x[1],2)))

答案 1 :(得分:1)

一种选择是使用距离的标准偏差作为第二个键。这样可以将您的2个排序逻辑组合在一个算法中。

import numpy as np

f1 = 20
f2 = 50
f = [(a, b) for a in range(f1-3, f1+4) for b in range(f2-3, f2+4)]

res = sorted(f, key=lambda x: [abs(f1-x[0]) + abs(f2-x[1]),
                               np.std([abs(f1-x[0]), abs(f2-x[1])])])

# [(20, 50), (19, 50), (20, 49), (20, 51), (21, 50), (19, 49), (19, 51), (21, 49), (21, 51), (18, 50), (20, 48), (20, 52), (22, 50), (18, 49), (18, 51), (19, 48), (19, 52), (21, 48), (21, 52), (22, 49), (22, 51), (17, 50), (20, 47), (20, 53), (23, 50), (18, 48), (18, 52), (22, 48), (22, 52), (17, 49), (17, 51), (19, 47), (19, 53), (21, 47), (21, 53), (23, 49), (23, 51), (17, 48), (17, 52), (18, 47), (18, 53), (22, 47), (22, 53), (23, 48), (23, 52), (17, 47), (17, 53), (23, 47), (23, 53)]

答案 2 :(得分:1)

对于问题1,我会选择@vlad发布的答案:使用几何距离。

假设这适合你,你可以用几何术语来看问题2:让f1为X轴,f2为Y轴。等距离(f1,f2)的频率元组将位于(f1,f2)周围的圆上。中心点(f1,f2)所在的位置无关紧要,最近的点将始终与(f1,f2)相同(x,y)偏移。这意味着您可以一次性计算这些偏移的排序,然后将它们添加到您感兴趣的任何(f1,f2)中。

# do this once, and keep this variable around
offsets = [(a, b) for a in range(-3, +4) for b in range(-3, +4)]
offsets.sort(key=lambda x: x[0] ** 2 + x[1] ** 2) 

# for any f1, f2 get the closest tuples
closest = [(f1 + o[0], f2 + o[1]) for o in offsets]