开发者

Efficient way to write this expression: English alphabets dictionary

开发者 https://www.devze.com 2023-01-23 14:27 出处:网络
What would be an efficient and the right way to implement this expression? {\'a开发者_开发知识库\': 1, \'b\': 2 ... \'z\': 26}

What would be an efficient and the right way to implement this expression?

{'a开发者_开发知识库': 1, 'b': 2 ... 'z': 26}

I have tried:

x = dict(zip(chr(range(ASCII of A, ASCII of Z)))

Something like this? But I can't figure out the correct expression.


>>> from string import lowercase
>>> dict((j,i) for i,j in enumerate(lowercase, 1)) 
{'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}

enumerate(lowercase) returns this sequence (0, 'a'), (1, 'b'), (2, 'c'),...

by adding the optional parameter, enumerate starts at 1 instead of 0

enumerate(lowercase, 1) returns this sequence (1, 'a'), (2, 'b'), (3, 'c'),...

The optional parameter is not supported by python older than 2.6, so you could write it this way instead

>>> dict((j,i+1) for i,j in enumerate(lowercase)) 


 dict((chr(x + 96), x) for x in range(1, 27))


You are on the right track, but notice that zip requires a sequence.

So this is what you need:

alphabets = dict(zip([chr(x) for x in range(ord('a'), ord('z')+1)], range(1, 27)))

ord returns the integer ordinal of a one character string. So you can't do a chr(sequence) or an ord(sequence). It has to be a single character, or a single number.


I'm not sure of an exact implementation, but wouldn't it make sense to use the ASCII codes to your advantage as they're in order? Specify the start and end then loop through them adding the ASCII character and the ASCII code minus the starting point.


dictionary comprehension:

{chr(a + 96):a for a in range(1,27)}

>>> {chr(a + 96):a for a in 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}

this only works in versions of python that support dictionary comprehensions, e.g. 3.x and i think 2.7


Guess I didn't reat the question closely enough. Fixed

dict( (chr(x), x-ord('a') +1 ) for x in range(ord('a'), ord('z')+1))


Is a dictionary lookup really what you want? You can just have a function that does this:

def getNum(ch):
    return ord(ch) - ord('a') + 1

This is pretty simple math, so it is possibly more efficient than a dictionary lookup, because the string doesn't need to be hashed and compared.

To do a dictionary lookup, the key you are looking for needs to be hashed, then it needs to find where that hash is in the dictionary. Next, it has to compare the key to the key it found to determine if it is the same or if it is a hash collision. Then, it has to read the value at that location.

The function just needs to do a couple additions. It does have the overhead of a function call though, so that may make it less efficient than a dictionary lookup.

Another thing you may need to consider is what each solution does if the input is invalid (not 'a' - 'z', for example capital 'A'). The dictionary solution would raise a KeyError. You could add code to catch errors if you used a function. If you were to use 'A' with the in-place solution you would get a wrong result, but no error would be raised indicating that you had invalid input.

The point is that in addition to asking "What would be an efficient way to implement this expression?", you should also be asking (at least asking yourself) is "Is this expression really what I want?" and "Is the more efficiency worth the trade-offs?".

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号