Home > Blockchain >  How to map each character in a string to a value?
How to map each character in a string to a value?

Time:07-11

If I had this set of items like this:

(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)

How would I go about assigning them to each character from this:

string = 'python'

To this:

(p, y, t, h, o, n) = (15, 24, 19, 7, 14, 13)

Thanks in Advance

CodePudding user response:

If you are trying to establish a mapping between two tuples from a mapping between two elements, you can try to use comprehensions and convert it to tuple, like this example:

# a mapping on elements, not necessarily lambda
f = lambda x: x*2
# a tuple that you want to map from
t1 = (1,2,3)
# comprehension ( a generator object )
t2 = (f(x) for x in t1)
# convert it into a tuple. Output: (2, 4, 6)
print(tuple(t2))

Converting a string to a tuple can be done in a similar manner:

s = "Hello"
t = (x for x in s)
print(tuple(t)) # output ('H', 'e', 'l', 'l', 'o')

CodePudding user response:

If the only logic to use is to assign numbers to each alphabet serially, then we can use a simply loop over letters in the string and get there index from a string which stores all the alphabets.

letters = "abcdefghijklmnopqrstuvwxyz"

string = "python"

print([x for x in string], [letters.index(i) for i in string ])

OUTPUT

['p', 'y', 't', 'h', 'o', 'n'] [15, 24, 19, 7, 14, 13]

CodePudding user response:

You could use the builtin ord function, and do the assignment using the locals function to update the current variable in use locally.

>>> string = 'python'
>>> toinclude = dict(zip(string,map(lambda x:ord(x)-97,string)))
>>> toinclude
{'p':15,'y':24,'t':19,'h':7,'o':14,'n':13}
>>> locals().update(toinclude)
>>> p
15

you could also use the string library

>>> from string import ascii_lowercase
>>> string = 'python'
>>> toinclude = dict(zip(string,map(ascii_lowercase.index,string.lower())))
>>> toinclude
{'p':15,'y':24,'t':19,'h':7,'o':14,'n':13}
>>> locals().update(toinclude)
>>> y
24

SIDENOTE: the first method is a little bit slower but doesn't rely on any library, to make work the second method without any library use this:

>>> ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz'

CodePudding user response:

You can use the module string for a quick access to the characters of the alphabet via ascii_lowercase attribute, not mandatory but faster than write them by hand.

Your idea to turn each character of the string into a variable... is a bad programming pattern... for example what would happen if the string has 100 characters? Simply you spam the main scope with variables or you risk to overwrite other variables as well. Further, you need to create a string to be evaluated as a python command (or play around with locals/globals) which is usually an hazard. That's why I divided my answer into two parts:

Part 1: use a dictionary to stores the characters and indices

from string import ascii_lowercase

string = 'pyhton'

# get indices
mapper = dict(map(reversed, enumerate(ascii_lowercase)))
string_indices = map(mapper.get, string.lower())

# dictionary of chars-indices keys-values
string_dict = dict(zip(string, string_indices))
#{'p': 15, 'y': 24, 'h': 7, 't': 19, 'o': 14, 'n': 13}

print(*zip(*string_dict.items()))
#('p', 'y', 'h', 't', 'o', 'n') (15, 24, 7, 19, 14, 13)

# index of the h-character in python
print(string_dict['h'])
#7

Part 2: evaluation part with exec

Notice: introduce a auxiliary variable, chars, to keep reference of the tuple. Its name can be modified to be sure to avoid conflicts.

# string statement for tuple evaluation
statement = 'chars = {} = {}'.format('(' ', '.join(tuple(string)) ')', tuple(string_dict.values()))
print(statement)
#chars = (p, y, h, t, o, n) = (15, 24, 7, 19, 14, 13)

# execute the statement
exec(statement, None, None)

# the tuples
print(chars)
#(15, 24, 7, 19, 14, 13)

# index of the h-character in python
print(h)
#7

With both parts you may have access to the data and the difference is quite minimal: string_dict['h'] VS h but the side-effects are big. I recommend to stop at part 1 and used part 2 as a theoretical exercise.

CodePudding user response:

If I understand you correctly, you're looking for a way to create the mapping between each character to its corresponding index position. So here maybe what you're searching:

from string import *

>>> ascii_lowercase               # string constants from string module
'abcdefghijklmnopqrstuvwxyz'
>>> mapping = {ch: idx for idx, ch in enumerate(ascii_lowercase)} # dictionary comprehension here
>>> mapping
{'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25}
>>> mapping.get('p')
15
>>> mapping.get('h')
7
>>> mapping.get('o')
14

>>> [mapping.get(c) for c in 'python'] # <--- this is what you want

Edit -

based on @triplee suggested, you can also do ord directly:

ord('p')    #  112 - 97 = 15
ord('a')    #  97 

# convert each character to it's index:
mapping = [ord(c)-97 for c in s]   # then you can do the rest of work...
  • Related