4

我有一个很大的数字列表,我想看看它们中的任何一个是否大致相等。如果 2 个数字“大约相等”(出于我的目的),则它们都落在彼此的 10% 范围内(请参阅以下 2 个示例。)然后我想将它们分类到大约相等的数字的单独列表中。

示例 #1 比较 5.0 和 5.5: 5.5 +/- 10% = 4.95 到 6.05(并且 5.0 在此范围内) 5.0 +/- 10% = 4.50 到 5.50(并且 5.5 在此范围内) 因此,5.0 和 5.5 是大约相等。

示例 #2 比较 5.0 和 5.6: 5.6 +/- 10% = 5.04 到 6.16(并且 5.0 在此范围内) 5.0 +/- 10% = 4.50 到 5.50(并且 5.6 不在此范围内) 因此,5.0 和 5.6不近似相等。

我需要做的总结:输入 = {4.0, 4.1, 4.2, 4.0, 9.0, 9.4, 8.9, 4.3} 期望的输出 = {4.0, 4.1, 4.2, 4.0, 4.3} 和 {9.0, 9.4, 8.9}

4

3 回答 3

3
input_list = [4.0, 4.1, 4.2, 4.0, 9.0, 9.4, 8.9, 4.3]

results = {input_list[0]: [input_list[0]]}    # Start with first value
for value in input_list[1:]:         # loop through our entire list after first value
    hi = value * 1.1
    low = value * 0.9
    print("Value: {0}\tHi: {1}\tLow:{2}".format(value, hi, low))
    for existing in results:     # search through our result set
        found_similar = False
        if low < existing < hi:  # if we find a match
            results[existing].append(value)    # we add our value to the list for that set
            found_similar = True
            break
    if not found_similar:        # if we looped through our entire results without a match
        results[value] = [value] # Create a new entry in our results dictionary

for entry in results:
    print(results[entry])

会给:

results = { 9.0: [9.0, 9.4, 8.9],
            4.0: [4.0, 4.1, 4.2, 4.0, 4.3] }

此代码从列表中的第一个值开始,并查找在该值 10% 范围内的所有后续值。因此,在您的示例中,它以 4 开头,并找到所有相似的值。任何不在 10% 以内的值都会被添加到新的“集合”中。

所以一旦它达到 9.0,它就会发现它不匹配,所以它向results字典添加一个新的结果集,键为9.0. 现在,当它考虑 9.4 时,它在 4.0 列表中没有找到匹配项,但它确实在 9.0 列表中找到了匹配项。所以它将这个值添加到第二个结果集中。

于 2013-05-07T23:34:10.987 回答
0

这是一个基于生成器/集合的方法。

def set_gen(nums):
    for seed in sorted(nums):
        yield tuple([n for n in nums if seed <= n and n/seed <= 1.1])

def remove_subsets(sets):
    for s in sets.copy():
        [sets.remove(s2) for s2 in sets.difference([s]) if set(s2).issubset(s)]

>>> nums = [4.0, 4.1, 4.2, 4.0, 9.0, 9.4, 8.9, 4.3]
>>> x = set(num for num in set_gen(nums))
>>> remove_subsets(x)
>>> list(x)
[(9.0, 9.4, 8.9), (4.0, 4.1, 4.2, 4.0, 4.3)]

>>> nums =  [1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0]
>>> x = set(num for num in set_gen(nums))
>>> remove_subsets(x)
>>> list(x)
[(1.9, 1.8), (1.5, 1.4), (1.4, 1.3), (1.2, 1.1), (1.7, 1.6), (1.5, 1.6), (1.3, 1.2), (1.9, 2.0), (1.0, 1.1), (1.8, 1.7)]
于 2013-05-08T00:16:00.527 回答
-1

你可以这样做:

Input = {4.0, 4.1, 4.2, 4.0, 9.0, 9.4, 8.9, 4.3} 

wl=sorted(Input,reverse=True)
apr=.1
out={}
while wl:
    wn=wl.pop()
    out[wn]=[wn]
    while wl and wl[-1]<=wn*(1+apr):
        out[wn].append(wl.pop())

print [(k,out[k]) for k in sorted(out.keys())]

印刷:

[(4.0, [4.0, 4.1, 4.2, 4.3]), (8.9, [8.9, 9.0, 9.4])]

尝试评论中的示例:

>>> Input = {1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0}

印刷:

[(1.0, [1.0, 1.1]), (1.2, [1.2, 1.3]), (1.4, [1.4, 1.5]), (1.6, [1.6, 1.7]), (1.8, [1.8, 1.9]), (2.0, [2.0])]
于 2013-05-07T23:42:51.000 回答