以特定顺序生成元组列表

问题描述 投票:2回答:3

所以这是我的问题。我有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))消除,但后来我失去了没有排序所获得的时间......

谢谢。

python list
3个回答
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]

3
投票

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

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

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)]
© www.soinside.com 2019 - 2024. All rights reserved.