How to reverse lookup characters in list?

Andrew Dalke adalke at mindspring.com
Mon Jul 28 06:46:28 EDT 2003


Keith Jones
> import string
> string.lowercase
>
> that gives you a-z, lowercase..

Actually, use 'string.ascii_lowercase' because 'string.lowercase' depends
on your locale.

On the other hand, for this application, string.lower might be the right
thing.

Also, the tjland?  You need to change the

    c = c + v
into
    c = (c + v) % len(alphabet)

Suppose c is 'z' and v is 2.  Then 25 (the position of the 'z') + 2 is 27,
which
is beyond the list of letters.  You need some way to loop around to 0 once
you go over the end, and the '%' is the loop-around operator.  (It's
actually
called the mod function.)  It also works the other way, so "-1 % 26" loops
around to 25.

You might find this helpful

>>> s = "testing"
>>> v = 2
>>> letters = string.ascii_lowercase
>>> t = ""
>>> for c in s:
...  t = t + letters[(letters.index(c)+v)%len(letters)]
...
>>> t
'vguvkpi'
>>> s = t
>>> v = -2
>>> t = ""
>>> for c in s:
...  t = t + letters[(letters.index(c)+v)%len(letters)]
...
>>> t
'testing'
>>>

With a bit more experience, I think you'll find this also interesting

v = 2

# Start by mapping each letter to itself
#  (There are 256 possible values in an 8-bit character.)
encoding_d = {}
for i in range(256):
  c = chr(i)
  encoding_d[c] = c

lc = string.ascii_lowercase
for i in range(len(lc)):
  from_char = lc[i]
  to_char = lc[(i+v) % len(lc)]
  encoding_d[from_char] = to_char

uc = string.ascii_uppercase
for i in range(len(uc)):
  from_char = uc[i]
  to_char = uc[(i+v) % len(uc)]
  encoding_d[from_char] = to_char

s = "This is a test."

# This is better written as:
#   t = "".join([encoding_d[c] for c in s])
# but that's something to try out after you learn a
# bit more Python.

t = ""
for c in s:
  t = t + encoding_d[c]

print t

# Make a decoding dictionary which is the opposite of the
# encoding dictionary
decoding_d = {}
for from_char, to_char in encoding_d.items():
  decoding_d[to_char] = from_char

# or as:  u = "".join([decoding_d[c] for c in t])
u = ""
for c in t:
  u = u + decoding_d[c]

print u

With some more experience beyond that, you might write it like this
(It uses a very different style and implementation)

import string

def _r(s, n):
  # rotate the characters left n positions
  n %= len(s)  # make sure it's properly within range
  return s[n:] + s[:n]

class RotEncoder:
 def __init__(self, n):
    from_letters = string.ascii_lowercase + string.ascii_uppercase
    to_letters = _r(string.ascii_lowercase, n) + _r(string.ascii_uppercase,
n)
    self.encode_table = string.maketrans(from_letters, to_letters)
    self.decode_table = string.maketrans(to_letters, from_letters)
 def encode(self, s):
    return string.translate(s, self.encode_table)
 def decode(self, s):
    return string.translate(s, self.decode_table)

code = RotEncoder(2)
print code.encode("testing")
print code.decode(code.encode("testing"))

                    Andrew
                    dalke at dalkescientific.com






More information about the Python-list mailing list