大多数pythonic方式找到匹配的字符串

时间:2018-06-08 13:53:33

标签: python python-3.x

在下面发布代码我该如何改进它的实现?我不想在我的代码中使用if-logic,我很确定Python中有更快的机制来处理这些任务:

      is_sat = re.search('sat', destination, re.IGNORECASE) 
      if is_sat is not None:
            temp_zone = self.determine_zone(value, self.sat_zone_dict)
            data_type = 'SAT' + str(temp_zone)
            self.log_handler.update(destination+" "+data_type+"\n")
        else:
            if destination.find("All") > 0:
                temp_zone = self.determine_zone(value, self.mn_zone_dict)
                data_type = 'ALL_' + str(temp_zone)
                self.log_handler.update("ALL destination: "+destination + " " + data_type + "\n")
            elif destination.find("Mobile") > 0:
                temp_zone = self.determine_zone(value, self.mn_zone_dict)
                data_type = 'MOB_'+str(temp_zone)
            elif destination.find("Fixed") > 0:
                temp_zone = self.determine_zone(value, self.mn_zone_dict)
                data_type = 'FIX_'+str(temp_zone)
            elif destination.find("NGN") > 0:
                temp_zone = self.determine_zone(value, self.sat_zone_dict)
                data_type = 'NGN_' + str(temp_zone)

determine_zone()方法允许我匹配key:value dict,但是当我首先必须在目标字段中搜索模式时,添加另一个操作是没有意义的准确地提取"全部'移动'的位置。在我的字符串中。

@EDIT 正如@zwer在这里问的是 determine_zone()实现:

 def determine_zone(price: int, zone_dict: dict) -> int:

     zone = None

     try:
         for (key, value) in zone_dict.items():
             if price < value:
                 zone = key
                 return zone

         if zone is None:
             zone = zone_dict.__len__() + 1
             return zone

     except TypeError:
         raise TypeError

2 个答案:

答案 0 :(得分:1)

将公共代码排除在外。无论你在哪里看到任何复制粘贴的代码(并发布了大量的代码),它都是一个有效的分解目标 - 不一定是单独的函数,而是以防止它被重复的方式。

is_sat = ...
# temp_zone is calculated only once, and turned to string immediately.
temp_zone = str(self.determine_zone(value, self.sat_zone_dict))
if is_sat is None: 
   for prefix in ('ALL', 'MOB', 'FIX', 'NGN'):
     if prefix in destination:
       data_type = prefix + '_' + temp_zone  # Only once.
       if prefix == 'ALL':
         log("ALL destination: "+destination + " " + data_type + "\n") 
   # You _might_ have a case where none of the prefix values were found.
   # Think about handling it, or make sure it cannot happen. 
else:
  data_type = 'SAT_' + temp_zone
  self.log_handler.update(destination + " " + data_type + "\n")

基本上就是这样。

答案 1 :(得分:0)

据我所知,你的逻辑完全相同,只有data_type值不同(在两个实例中,你传递给self.determine_zone()的dict)。您可以创建一个小的查找字典,然后迭代它直到找到您的候选人,例如:

# sadly, the first check doesn't appear to follow the same rules - i.e. it's case insensitive
# you'll have to do it manually, i.e.:
if "sat" in destination.lower():
    temp_zone = self.determine_zone(value, self.sat_zone_dict)
    data_type = 'SAT' + str(temp_zone)
    self.log_handler.update(destination + " " + data_type+"\n")
else:
    lookup = {"All": ["ALL_", self.mn_zone_dict],
              "Mobile": ["MOB_", self.mn_zone_dict],
              "Fixed": ["FIX_", self.mn_zone_dict],
              "NGN": ["FIX_", self.sat_zone_dict]}  # add as many mappings as needed
    for k, v in lookup.items():
        if k in destination:
            temp_zone = self.determine_zone(value, v[1])
            data_type = v[0] + str(temp_zone)
            self.log_handler.update(destination + " " + data_type+"\n")
            break

然而,这可能会给你更多的功能,如果你有很多条件需要添加,可能看起来更整洁,但它不会大大提高性能。无论如何,我认为你的性能瓶颈并不存在。