我有一个输入列表,说:
L = [1, 1.3, 2, 2.5]
我想迭代排序对,以便该对的每一端都适合
L
中的两个不同值。在这种情况下,可接受的创建的配对列表是:
[(0.5, 1.2), (0.5, 1.4), (0.5, 2.1), (0.5, 2.6), (1.1, 1.4), (1.1, 2.1), (1.1, 2.6), (1.4, 2.1), (1.4, 2.6), (2.1, 2.6)]
对中的第一个元素允许小于 L 中的最小值,对中的第二个元素可以大于 L 中的最大值,如示例所示。
我不介意这些对中的确切值是什么,只要它们与
L
中的任何值不同即可。
你怎么能做到这一点?我想迭代这个对列表,而不是计算完整列表并存储它。
您可以在 Python 中使用
itertools
模块来完成此操作,该模块提供了用于迭代器的各种函数以生成复杂的迭代器。在这里,itertools.combinations
可用于从列表中生成对,然后稍微调整这些对以确保没有一个值与输入列表中的任何值相同。
为了生成调整后的对,可以使用简单的生成器函数,如下所示,
import itertools
def generate_pairs(L):
L = sorted(L)
L.insert(0, L[0]-1) # Add a smaller value at the beginning
L.append(L[-1]+1) # Add a larger value at the end
for pair in itertools.combinations(L, 2):
# Adjust pair to ensure neither value is the same as any in the original list
adjusted_pair = (pair[0]+0.1, pair[1]-0.1)
yield adjusted_pair
L = [1, 1.3, 2, 2.5]
for pair in generate_pairs(L):
print(pair)
此处,通过将第一个值加上 0.1 并从第二个值中减去 0.1 来调整对。您可以根据需要更改此值,只需确保调整后,这些对仍然适合原始列表中的两个不同值之间。
我假设原始列表已排序,如果没有排序,那么您可以在生成对之前添加一行代码对其进行排序。
这个问题分解为两个独立的问题:
创建一个包含 𝑛 + 1 个值的列表,其中外部两个值超出输入范围(比第一个值小一个,比最后一个值多一个),内部值是输入中每个连续对的平均值.
从值列表中生成所有可能的(已排序的)对。这可以通过
itertools.combinations
来完成。
代码:
from itertools import combinations
def mids(lst):
return lst and [lst[0]-1] + [sum(p)/2 for p in zip(lst, lst[1:])] + [lst[-1]+1]
lst = [1, 1.3, 2, 2.5]
for pair in combinations(mids(lst), 2):
print(pair)
我有两种方法。第一个涉及找到中点,其他人已经提出过。
在第二种方法中,我将首先找到数字对之间的所有差异。所以对于
L = [1, 1.3, 2, 2.5]
差异为0.3、0.7、0.5。最小差异为 0.3。为了确保不与输入发生冲突,我将这个最小差异除以 2,得到 0.15,我将其称为增量。从那里,对于每个元素,我只需计算并返回(元素 - 增量,元素 + 增量)。
def brackets(seq):
# Asume seq not sorted
seq = sorted(seq)
# Calculate delta: half of the smallest difference
# between the pairs of input
list1 = iter(seq)
list2 = iter(seq)
next(list2)
delta = min(b - a for a, b in zip(list1, list2)) / 2.0
out = [
(element - delta, element + delta)
for element in seq
]
return out
示例运行:
>>> brackets([1, 1.3, 2, 2.5])
[(0.85, 1.15), (1.15, 1.4500000000000002), (1.85, 2.15), (2.35, 2.65)]