【问题标题】:Simplifying many if-statements简化许多 if 语句
【发布时间】:2019-03-07 17:36:32
【问题描述】:

有没有办法简化这堆 if 语句?这个解析函数确实有效(使用正确的字典),但它必须为输入中的每个单词测试 6 个 if 语句。对于一个 5 个单词的句子,这将是 30 个 if 语句。它也有点难以阅读。

def parse(text):
    predicate=False
    directObjectAdjective=False
    directObject=False
    preposition=False
    indirectObjectAdjective=False
    indirectObject=False
    text=text.casefold()
    text=text.split()
    for word in text:
        if not predicate:
            if word in predicateDict:
                predicate=predicateDict[word]
                continue
        if not directObjectAdjective:
            if word in adjectiveDict:
                directObjectAdjective=adjectiveDict[word]
                continue
        if not directObject:
            if word in objectDict:
                directObject=objectDict[word]
                continue
        if not preposition:
            if word in prepositionDict:
                preposition=prepositionDict[word]
                continue
        if not indirectObjectAdjective:
            if word in adjectiveDict:
                indirectObjectAdjective=adjectiveDict[word]
                continue
        if not indirectObject:
            if word in objectDict:
                indirectObject=objectDict[word]
                continue
    if not directObject and directObjectAdjective:
        directObject=directObjectAdjective
        directObjectAdjective=False
    if not indirectObject and indirectObjectAdjective:
        indirectObject=indirectObjectAdjective
        indirectObjectAdjective=False
    return [predicate,directObjectAdjective,directObject,preposition,indirectObjectAdjective,indirectObject]

如果需要,这里还有一个字典样本。

predicateDict={
"grab":"take",
"pick":"take",
"collect":"take",
"acquire":"take",
"snag":"take",
"gather":"take",
"attain":"take",
"capture":"take",
"take":"take"}

【问题讨论】:

标签: python if-statement simplify simplification


【解决方案1】:

这更像是一个代码审查问题,而不是堆栈溢出问题。一个主要问题是您将类似的数据保存在单独的变量中。如果你组合你的变量,那么你可以迭代它们。

missing_parts_of_speech = ["predicate", [...]]
dict_look_up = {"predicate":predicateDict,
           [...]           
        }    
found_parts_of_speech = {}    
for word in text:
    for part in missing_parts_of_speech:
        if word in dict_look_up[part]:
            found_parts_of_speech[part] = dict_look_up[part][word]
            missing_parts_of_speech.remove(part)
            continue

【讨论】:

  • 基本上和我的想法一样,但是使用三个字典/列表而不是一个可能确实更好。
【解决方案2】:

我建议简单地使用方法dict.get。此方法具有可选参数default。通过传递此参数,您可以避免KeyError。如果键不存在于字典中,则返回默认值。

如果您使用之前分配的变量作为默认值,它将不会被任意值替换,而是正确的值。例如,如果当前单词是“谓词”,则“直接对象”将被替换为已经存储在变量中的值。


代码

def parse(text):
    predicate = False
    directObjectAdjective = False
    directObject = False
    preposition = False
    indirectObjectAdjective = False
    indirectObject = False

    text=text.casefold()
    text=text.split()
    for word in text:
        predicate = predicateDict.get(word, predicate)
        directObjectAdjective = adjectiveDict.get(word, directObjectAdjective)
        directObject = objectDict.get(word, directObject)
        preposition = prepositionDict.get(word, preposition)
        indirectObjectAdjective = adjectiveDict.get(word, indirectObjectAdjective)
        indirectObject = objectDict.get(word, indirectObject)

    if not directObject and directObjectAdjective:
        directObject = directObjectAdjective
        directObjectAdjective = False

    if not indirectObject and indirectObjectAdjective:
        indirectObject = indirectObjectAdjective
        indirectObjectAdjective = False

    return [predicate, directObjectAdjective, directObject, preposition, indirectObjectAdjective, indirectObject]

PS:使用更多的空间。读者会感谢你...


PPS:我没有测试过这个,因为我手头没有这样的字典。


PPPS:这将始终返回文本中类型的最后次出现,而您的实现将始终返回第一次次出现。

【讨论】:

    【解决方案3】:

    您可以将不同种类的单词(作为字符串)映射到字典中以查找这些单词,然后只需检查其中哪些尚未找到并查找它们是否在这些字典中。

    needed = {"predicate": predicateDict,
              "directObjectAdjective": adjectiveDict,
              "directObject": objectDict,
              "preposition": prepositionDict,
              "indirectObjectAdjective": adjectiveDict,
              "indirectObject": objectDict}
    
    for word in text:
        for kind in needed:
            if isinstance(needed[kind], dict) and word in needed[kind]:
                needed[kind] = needed[kind][word]
                continue
    

    最后(以及沿途的每一步)needed 中没有dict 作为值的所有项目都已找到并替换为各自dict 中的值。

    (回想起来,使用两个字典,或者一个字典和一个集合可能更有意义:一个用于那种单词的最终值,一个用于是否已经找到它们。可能有点更容易掌握。)

    【讨论】:

      【解决方案4】:

      我建议您使用新模式来编写此代码,而不是旧模式。新模式有 9 行并保持 9 行 - 只需在 D 中添加更多字典。旧模式已经有 11 行,并且每增加一个字典就会增加 4 行进行测试。

      aDict = { "a1" : "aa1", "a2" : "aa1" }
      bDict = { "b1" : "bb1", "b2" : "bb2" }
      text = ["a1", "b2", "a2", "b1"]
      # old pattern
      a = False
      b = False
      for word in text:
          if not a:
              if word in aDict:
                  a = aDict[word]
                  continue
          if not b:
              if word in bDict:
                  b = bDict[word]
                  continue
      print(a, b)
      # new pattern
      D = [ aDict, bDict]
      A = [ False for _ in D]
      for word in text:
          for i, a in enumerate(A):
              if not a:
                  if word in D[i]:
                      A[i] = D[i][word]
                      continue
      print(A)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-12
        • 1970-01-01
        • 2020-03-15
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多