【问题标题】:if elif with stringsif elif 带字符串
【发布时间】:2013-01-13 00:04:03
【问题描述】:

我正在重构一些包含大量代码的脚本:

if 'mString1' in mStrVar:
    retVal = 1
elif 'mString2' in mStrVar:
    retVal = 2
elif 'mString3' in mStrVar:
    retVal = 3
elif 'mString4' in mStrVar:
    retVal = 4
else:
    retVal = 0

我个人不喜欢这种方式,我总是更喜欢dict() 方法,但在这种特定情况下,我认为我不能那样做。

是否可以用更短的方式重写它? mString 在某些情况下会绕过 mString10

高度赞赏任何提示,如果这是重复的,我无法找到任何相关的问题,我们深表歉意。

【问题讨论】:

  • 您的问题到底是什么? mStrVar 是什么?
  • 这段代码你不喜欢什么?
  • 如果mStrVar = "mString1mString2mString3mString4" 会怎样?恕我直言,将子字符串映射到单个数字的逻辑本身已经很脆弱。
  • 另外,与正则表达式匹配可能更明确一些,并且可能能够在一次遍历字符串的过程中提取匹配的字符串。
  • mString1mString10 中,所以如果你使用这种方法,你需要注意顺序(我认为最长的优先应该有效,但我没有给出太多想。)

标签: python string python-2.7


【解决方案1】:

您可以创建一个映射列表并使用普通的 for 循环来搜索 mStrVar 变量中的字符串:

retVal_mapping = [
   ('mString1', 1),
   ('mString2', 2),
   ('mString3', 2),
   ('mString4', 2),
   ('', 0) # default as "'' in anyString" is always true.
]

for s, retVal in retVal_mapping:
    if s in mStrVar:
        break

# retVal now contains the right value

【讨论】:

    【解决方案2】:

    例如,如果您想使用正则表达式 mString(\d+),您可以这样做:

    # Precompile pattern into finite automaton:
    _pattern = re.compile(r'mString(\d+)')
    
    # Apply multiple times.
    match = _pattern.match(mStrVar)
    if match:
        retVal = int(match.group(1))
    else:
        retVal = 0
    

    上面的子字符串代码的问题是它的定义不是很好,例如 mStrVar = "mString1mString2mString3mString4"。正则表达式匹配实际上要严格得多,这可能是我们所希望的。

    对于非数字模式,您也可以使用dict 样式方法:

    # Precompile pattern:
    _pattern = re.compile(r'(abc|def|ghi)')
    _map = { 'def' : 1, 'ghi' : 2, 'abc' : 3 }
    
    match = _pattern.match(mStrVar)
    if match:
        retVal = _map.get(match.group(1), 0)
    else:
        retVal = 0
    

    在某些情况下,您也可以立即使用 dict:

    _map = { 'def' : 1, 'ghi' : 2, 'abc' : 3 }
    retVal = _map.get(mStrVar, 0) # 0 is default!
    

    【讨论】:

      【解决方案3】:
      some_dict = dict(mString1=1, mString2=2, mString3=3)
      return some_dict.get(string_value, 0)
      

      其中 string_value 是 mString1、mString2、mString3 之一。

      【讨论】:

      • 如果mStrVar中可以找到多个术语,则不等同于原始代码。
      • 你忘了检查mStringN是否在mStrVar
      • 如果在 mStrVal 中为 no,则返回 0。
      【解决方案4】:
      mylist = ['mString1', 'mString2', 'mString3', 'mString4']
      retVal = [i for i in range(len(mylist)) if mylist[i] = mStrVar][0] + 1
      

      【讨论】:

        【解决方案5】:
        retval, = [i for i in xrange(1, 5) if 'mString%s' % i in mStrVar] or [0]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-07-18
          • 1970-01-01
          • 1970-01-01
          • 2011-02-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-15
          • 1970-01-01
          相关资源
          最近更新 更多