【问题标题】:switch-case statement for STRINGS in PythonPython中字符串的switch-case语句
【发布时间】:2018-08-17 13:16:53
【问题描述】:

我需要做一些类似于 CASE WHEN .. OR .. THEN from SQL in python for STRINGS 的事情。例如,如果我说“DOG”或“CAT”……我的翻译是“ANIMAL”。

我不想使用 IF ELIF ELIF..

我能看到的唯一解决方案是:

l = ['cat','dog', 'turttle']
d = {'animal': ['cat','dog', 'turttle']}
word = 'cat'
if word in l:
    for i, j in d.iteritems():
        if word in j:
            print i
        else:
            print word

animal

它可以工作,但看起来很丑..

还有其他解决方案吗?

谢谢!

【问题讨论】:

    标签: python dictionary switch-statement case type-synonyms


    【解决方案1】:

    出于您的目的,我建议您使用按动物名称索引的字典。代码中的l 列表也将是多余的,因为它只是这个字典的键。

    d = {
        'cat': 'animal',
        'dog': 'animal',
        'turtle': 'animal'
    }
    word = 'cat'
    print(d.get(word, word))
    

    【讨论】:

    • .. 但是,如果我有 1M 的单词和翻译会发生什么?
    • dict 仍然是最快的实现,因为它允许 O(1) 的平均查找时间。您应该始终使用要查找的内容作为键,而不是相反。
    • 对于 dict,获取项目是 O(1)“平均情况”和 O(n)“摊销最坏情况”。我希望有一个更像在 C 中使用跳转表的解决方案。来源:wiki.python.org/moin/TimeComplexity
    • @avatarofhope2,这是最不可能的最坏情况,例如连续 n 周中奖。
    【解决方案2】:

    你可以这样做:

    animal_list = ['cat','dog', 'turttle']
    plant_list = ['tree', 'grass']
    d = {'animal': animal_list, 'plant': plant_list}
    word = 'tree'
    for key, value in d.iteritems():
        if word in value:
            print key
    

    【讨论】:

    • 谢谢,这与我的解决方案类似。但是,如果我有 1M 的单词和翻译会发生什么?
    • 它可能会慢一点(我没有尝试与blhsing比较),但避免使用大字典
    • 在这个解决方案中,假设animal_list 和plant_list 没有重复的元素,您可以使用集合而不是列表。设置散列它们的元素,因此查找时间是 O(1)。无论您有 3 个元素还是 100 万个元素,所花费的时间都是相同的。
    【解决方案3】:
    d = {'animal': ['cat','dog', 'turttle']}
    
    word = 'cat'
    
    if word in d['animal']:
        print('animal')
    

    【讨论】:

      【解决方案4】:

      您可以使用几个基于数据结构的效率来扩展您的程序,如下所示:

      1. 使用字典存储分类为“动物”或其他的数据
      2. 使用集合而不是列表按分类进行分组。无论集合有多大,这都允许进行恒定时间查找。

      类似这样的:

      kingdom = {'animal':set(['Cat','Dog','Turtle']), 'plant':set(['Rosemary','Thyme'])}
      word = 'cat'
      for family in kingdom:
        if word in kingdom[family]: # here is where constant time lookup occurs
          print family
        else:
          print word
      

      或者,您可以为“动物”和“植物”等定义类...取决于“动物”或“植物”的特定功能有多少。我确实赞同避免占位符代码的原则,因此建议不要研究类,除非你有理由实现它。

      【讨论】:

        【解决方案5】:

        如果我有 100 万个单词和翻译会发生什么?

        另一种方法是以一种便于定义数据的方式存储数据,但在代码主体之前,将数据(一次)反转为对运行时更有效的形式:

        by_kingdoms = {
            'animal': {'cat', 'dog', 'turtle'},
            'plant': {'rosemary', 'thyme'},
        }
        
        by_families = {}
        
        for kingdom, families in by_kingdoms.items():
            for family in families:
                by_families[family] = kingdom
        
        word = 'cat'
        
        print(by_families[word])
        

        这假设数据结构良好,但您甚至可以通过将 by_families 字典列表的值设置为该家族可能出现的王国列表:

        from collections import defaultdict
        
        by_kingdoms = {
            'animal': {'cat', 'dog', 'turtle', 'bird of paradise'},
            'plant': {'rosemary', 'thyme', 'bird of paradise'},
        }
        
        by_families = defaultdict(list)
        
        for kingdom, families in by_kingdoms.items():
            for family in families:
                by_families[family].append(kingdom)
        
        word = 'bird of paradise'
        
        print(by_families[word])
        

        【讨论】:

          最近更新 更多