2014-03-26 69 views
3

我尝试通过查看它们是否在给定的范围内来分散一些数字,然后根据范围分配一个数字,但是我得到的结果并不完全正确。检查数字列表是否在一定范围内?

mapp是一个字典,它定义了范围,以及与给定范围相对应的值。

lst的是,我要匹配这些范围,并为其分配标识符给他们

mapp = {(0,100): 1, (100,400): 2, (400,800): 3} 


lst = [3.5, 5.4, 300.12, 500.78, 600.45, 900.546] 


def discretize(mapping_dict, list_of_values): 
    print "\n" 
    location = [] 
    for x in sorted(list_of_values): 
     for (lower_bound,upper_bound),value in mapping_dict.items(): 
      if round(x) in range(lower_bound,upper_bound): 
       print round(x), "yes", value 

       distance = mapping_dict[(lower_bound,upper_bound)] 
       location.append((distance)) 


     else: 
      print round(x), "no" 

      distance = len(mapping_dict.items())+10 
      location.append((distance)) 

    return location 

这是我想到的是结果号码的列表:[1, 1, 2, 3, 3, 13],但是这不是我所得到的。

这是实际的结果是我得到的,这是不正确的:

4.0 yes 1 
4.0 no   #wrong! 
5.0 yes 1 
5.0 no   #wrong! 
300.0 yes 2 
300.0 no   #wrong! 
501.0 yes 3 
501.0 no   #wrong! 
600.0 yes 3 
600.0 no   #wrong! 
901.0 no   #CORRECT 

[1, 13, 1, 13, 2, 13, 3, 13, 3, 13, 13] 

我在4.0得到no这是不正确的,等等,等等

问题出在哪里?

感谢

+1

你可能只需要一次从你找到合适的组循环'break',否则'else'就一定会执行。 –

+1

你绝对不想像你一样创造范围。你只需要使用'lower_bound <= val acushner

回答

3
mapp = {(0,100): 1, (100,400): 2, (400,800): 3} 
lst = [3.5, 5.4, 300.12, 500.78, 600.45, 900.546] 
result = [] 
for l in lst: 
    for m in mapp: 
     if m[0] < l < m[1]: 
      result.append(mapp[m]) 

print result 

输出:

[1, 1, 2, 3, 3] 

编辑:

result = [] 
for l in lst: 
    flag=True 
    for m in mapp: 
     if m[0] < l < m[1]: 
      result.append(mapp[m]) 
      flag = False 
      break 
    if flag: 
     result.append(-1) 
print result 

输出:

[1, 1, 2, 3, 3, -1] 
+0

谢谢,但这种解决方案仍然不考虑'900.546' @ user3的情况 –

+0

你如何计算900.546的值? – user3

+0

如果未定义范围,我已编辑添加-1 ... – user3

1

把一个elsefor循环之后你是一个在正确的轨道!当你输入else after a loop时,每当循环正常退出时,即不使用例如else块,该块被执行。 break。因此(假设你的组不重叠),你只需要在你的if块的末尾添加break语句,即在location.append((distance))之后。然后它按预期工作。

而不是检查数字是否在range(它每次创建和搜索列表!),您应该只使用<=<。另外,你已经有了value,为什么不使用它?

for (lower_bound, upper_bound), value in mapping_dict.items(): 
    if lower_bound <= x < upper_bound: 
     location.append(value) 
     break 
else: 
    location.append(len(mapping_dict) + 10) 
1

我想我已经遇到了类似的问题CE,因为我发现了一个小RangeDict类:

class RangeDict (dict): 
    def __init__ (self, *args): 
     super().__init__() 

    def __setitem__ (self, k, v): 
     if not isinstance (k, slice): raise ValueError ('Indices must be slices.') 
     super().__setitem__ ((k.start, k.stop), v) 

    def __getitem__ (self, k): 
     for (start, stop), v in self.items(): 
      if start <= k < stop: return v 
     raise IndexError ('{} out of bounds.'.format (k)) 

我希望这个类包装所需的funcionality。显然,查找是O(N)而不是O(1)。

使用范例:

r = RangeDict() 
r [0:100] = 1 
r [100:400] = 2 
r [400:800] = 3 

for x in [3.5, 5.4, 300.12, 500.78, 600.45, 900.546]: 
    print (r [x]) 
#Last value raises IndexError 
+1

+1整洁!只是好奇:为什么你不使用'if start <= k

+0

@tobias_k为了最小化比较。 – Hyperboreus

+0

虽然如此,但是不像'x

相关问题