【问题标题】:creating dict where keys are alphabet letters and values are 1-26 using dict comprehension创建字典,其中键是字母,值是 1-26 使用字典理解
【发布时间】:2013-11-01 19:06:30
【问题描述】:
alphaValueDict = OrderedDict.fromkeys(string.ascii_uppercase,range(0)
i = 1
for k,v in alphaValueDict.iteritems():
    alphaValueDict[k] = [i]
    i += 1
return alphaValueDict

我需要创建一个有序的 dict ,其中键是字母表中的所有字母,值是从 1 到 26。我的问题是,如何使用 dict 理解在一行中做到这一点?

【问题讨论】:

    标签: python dictionary dictionary-comprehension


    【解决方案1】:
    >>> import string
    >>> string.ascii_lowercase
    'abcdefghijklmnopqrstuvwxyz'
    >>> s= string.ascii_lowercase
    
    >>> from collections import OrderedDict
    >>> odict = OrderedDict()
    >>> for count,i in enumerate(s):
    ...     odict[count] = i
    ... 
    >>> odict
    OrderedDict([(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f'), (6, 'g'), (7, 'h'), (8, 'i'), (9, 'j'), (10, 'k'), (11, 'l'), (12, 'm'), (13, 'n'), (14, 'o'), (15, 'p'), (16, 'q'), (17, 'r'), (18, 's'), (19, 't'), (20, 'u'), (21, 'v'), (22, 'w'), (23, 'x'), (24, 'y'), (25, 'z')])
    

    【讨论】:

      【解决方案2】:

      最简单的方法是使用 zip 和元组解包

      import string
      { k: v for k, v in zip(string.ascii_uppercase, xrange(1, len(string.ascii_uppercase)+1))}
      

      已将 cmets 考虑在内。这是一个单行,没有 dict comp。 只依赖 OrderedDict 进行迭代和 zip 的强大功能。

      OrderedDict(zip(string.ascii_uppercase, xrange(1, len(string.ascii_uppercase)+1)))
      

      【讨论】:

      • 或者跳过字典理解,直接使用dict(zip(...))。
      • 也不是OrderedDict
      • 真;规范说“使用字典理解”;)
      • 我总是可以随意忽略规范中建议的实现。通常客户对实施有错误的想法,但他们可能知道他们想要什么结果。
      【解决方案3】:
      print {chr(ele+97): ele+1 for ele in xrange(26)}
      

      【讨论】:

        【解决方案4】:

        使用enumerate() 计算字母:

        >>> OrderedDict((k,v+1) for v,k in enumerate(string.ascii_uppercase))
        OrderedDict([('A', 1), ('B', 2), ('C', 3), ('D', 4), ('E', 5), ('F', 6), ('G', 7), ('H', 8), ('I', 9), ('J', 10), ('K', 11), ('L', 12), ('M', 13), ('N', 14), ('O', 15), ('P', 16), ('Q', 17), ('R', 18), ('S', 19), ('T', 20), ('U', 21), ('V', 22), ('W', 23), ('X', 24), ('Y', 25), ('Z', 26)])
        

        要回答帖子末尾的问题,dict 理解不是初始化OrderedDict 的合适方法。字典推导只会创建普通字典,如果你用它来初始化你的 OrderedDict 已经太晚了,你已经失去了任何排序。

        【讨论】:

          【解决方案5】:

          我的看法:

          from string import ascii_uppercase
          from collections import OrderedDict
          
          od = OrderedDict((ch, idx) for idx, ch in enumerate(ascii_uppercase, 1))
          

          或者:

          from itertools import count, izip
          od = OrderedDict(izip(ascii_uppercase, count(1)))
          

          【讨论】:

          • 计数是否随着 izip 中第一个参数的长度而增加?
          • 所以我不能说使用 count(2) 将值设为 2-4-6-8?
          • @PadraicCunningham 如果您阅读文档,您会发现它需要一个 step 参数,因此 count(2, 2) 将从 2 开始计算为 2...
          • 谢谢,我需要更加熟悉itertools,我提出的很多问题都使用itertools得到了解答
          【解决方案6】:

          您可以完全避免 dict-comprehension:

          >>> import string
          >>> dict(zip(string.ascii_lowercase, range(1,27)))
          {'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4, 'g': 7, 'f': 6, 'i': 9, 'h': 8, 'k': 11, 'j': 10, 'm': 13, 'l': 12, 'o': 15, 'n': 14, 'q': 17, 'p': 16, 's': 19, 'r': 18, 'u': 21, 't': 20, 'w': 23, 'v': 22, 'y': 25, 'x': 24, 'z': 26}
          

          OrderedDict:

          >>> import string
          >>> from collections import OrderedDict
          >>> OrderedDict(zip(string.ascii_lowercase, range(1,27)))
          OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7), ('h', 8), ('i', 9), ('j', 10), ('k', 11), ('l', 12), ('m', 13), ('n', 14), ('o', 15), ('p', 16), ('q', 17), ('r', 18), ('s', 19), ('t', 20), ('u', 21), ('v', 22), ('w', 23), ('x', 24), ('y', 25), ('z', 26)])
          

          仅当您必须进行更多计算以获取键/值或增强可读性时,我才会使用 dict-comprehension(极端示例:{noun : age for noun, age in something()} 让您了解我们在说什么,而 @ 987654325@ 没有)。

          【讨论】:

          • 当我迭代 5000 个名称的列表时,我将重复访问 dict 以获取每个字母的值,并对每个名称的总值求和。
          • @PadraicCunningham 在这种情况下,使用ord 可能更简单、更有效。对于每个名称,请执行以下操作:sum(map(ord, name)) - (ord('a') - 1) * len(name).
          • @Bakurlu,它适用于 Euler 项目。实际上,在我意识到字母的值被指定为从 1 到 26 与它们在字母表中的位置一致之前,我实际上开始这样做了,所以 ord 不起作用。除非我误解了你。
          • @PadraicCunningham 你误解了我的评论。 sum(map(ord, name)) 将对 ASCII 值求和。如果你减去(ord('a') - 1) * len(name),你会得到字母表中位置的总和(因为 ASCII 中的字母是连续且有序的)。您也可以写sum(ord(letter) - ord('a') + 1 for letter in name),其中ord(letter) - ord('a') + 1 是letter 在字母表中的位置。但是,由于您从每个元素中减去 ord('a')-1,您可以将其从总和中取出(因此是 (ord('a') - 1) * len(name))。
          • 抱歉,我不确定您的意思,我在解决方案论坛中看到很多人按照您的方式进行操作。
          【解决方案7】:

          使用基础:

          >>> from string import ascii_uppercase
          >>> from collections import OrderedDict
          

          一个班轮:

          >>> OrderedDict((k, i+1) for i, k in enumerate(ascii_uppercase))
          

          产量:

          OrderedDict([('A', 1), ('B', 2), ('C', 3), ('D', 4), ('E', 5), ('F', 6), ('G', 7), ('H', 8), ('I', 9), ('J', 10), ('K', 11), ('L', 12), ('M', 13), ('N', 14), ('O', 15), ('P', 16), ('Q', 17), ('R', 18), ('S', 19), ('T', 20), ('U', 21), ('V', 22), ('W', 23), ('X', 24), ('Y', 25), ('Z', 26)])
          

          【讨论】:

            【解决方案8】:

            不使用字典理解,扩展 dict 的变体:

            import string
            
            class alph(dict):
                def __getitem__(self, key):
                    if len(key) != 1:
                        raise ValueError("Not a character.")
                    return string.ascii_lowercase.index(key.lower()) + 1
            

            同时处理上下键并抛出 ValueError 错误键。

            【讨论】:

              【解决方案9】:
              theDict ={chr(y):y-64 for y in range(65,91)
              print theDict
              

              输出:

              {'A':1,'B':2,......'X':24,'Y':25,'Z':26}
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2018-06-21
                • 1970-01-01
                • 2021-10-25
                • 1970-01-01
                • 2018-12-07
                • 1970-01-01
                相关资源
                最近更新 更多