n611x007
n611x007

Reputation: 9272

How to map characters to integer range [-128, 127] in Python?

I would like to convert a list of characters (represented on a single byte ie. the range [0, 255]) to be represented with integers in the range [-128,127]. I've read that Python's modulo operator (%) always return a number having the same sign as the denominator.

What is the right way to do this conversion in Python?

EDIT Characters that map to [128,255] with ord should be remapped to [-128,-1], with 128 mapped to -128 and 255 mapped to -1. (For the inverse of the conversion I use chr(my_int%256), but my_int can be a negative number.)

Upvotes: 0

Views: 1778

Answers (5)

Mike Housky
Mike Housky

Reputation: 4069

This is an old question, but for future readers the straightforward solution for single integers is (x + 128)%256 - 128. Replace x with ord(c) if dealing with ASCII character data.

The result of the % operator there is congruent (mod 256) to x + 128; and subtracting 128 from that makes the final result congruent to x and shifts the range to [128,127].

This will work in a generator expression, and save a step in Python 3 where you'd need to convert a string to a bytes object.

Upvotes: 0

n611x007
n611x007

Reputation: 9272

I've found out that I could do this conversion with "unpacking from byte" with the struct module:

# gotcha|pitfall: my original idea, but this generates a list of 1-tuples:
# x = [struct.unpack("b",a) for a in charlist]

fmt = "%ib"%len(charlist) # eg. "5b", if charlist's length is 5
x = struct.unpack(fmt,charlist) # tuple of ints

Upvotes: 5

sberry
sberry

Reputation: 132108

def to_ints(input):
    return [o if o <= 128 else 255 - o for o in [ord(char) in input]]

def to_str(input):
    return "".join([chr(i%256) for i in input])

out = to_ints("This is a test")
print to_str(out)

Upvotes: 1

christophe31
christophe31

Reputation: 6467

Not sure if I understood the question... You want to do something like that?

[i - 255 if i > 127 else i for i in [ord(l) for l in "azertyuiopqsdféhjklm3{"]]

Upvotes: 2

user1149862
user1149862

Reputation:

I wonder what do you mean by "a list of characters", are they numbers? If so, I think x % 256 - 128 or x % -256 + 128 should work.

Upvotes: 0

Related Questions