[python] How do I convert a list of ascii values to a string in python?

I've got a list in a Python program that contains a series of numbers, which are themselves ASCII values. How do I convert this into a "regular" string that I can echo to the screen?

This question is related to python string ascii

The answer is


import array
def f7(list):
    return array.array('B', list).tostring()

from Python Patterns - An Optimization Anecdote


Question = [67, 121, 98, 101, 114, 71, 105, 114, 108, 122]
print(''.join(chr(number) for number in Question))

import array
def f7(list):
    return array.array('B', list).tostring()

from Python Patterns - An Optimization Anecdote


Same basic solution as others, but I personally prefer to use map instead of the list comprehension:


>>> L = [104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100]
>>> ''.join(map(chr,L))
'hello, world'

l = [83, 84, 65, 67, 75]

s = "".join([chr(c) for c in l])

print s

def working_ascii():
    """
        G    r   e    e    t    i     n   g    s    !
        71, 114, 101, 101, 116, 105, 110, 103, 115, 33
    """

    hello = [71, 114, 101, 101, 116, 105, 110, 103, 115, 33]
    pmsg = ''.join(chr(i) for i in hello)
    print(pmsg)

    for i in range(33, 256):
        print(" ascii: {0} char: {1}".format(i, chr(i)))

working_ascii()

l = [83, 84, 65, 67, 75]

s = "".join([chr(c) for c in l])

print s

You can use bytes(list).decode() to do this - and list(string.encode()) to get the values back.


I've timed the existing answers. Code to reproduce is below. TLDR is that bytes(seq).decode() is by far the fastest. Results here:

 test_bytes_decode : 12.8046 µs/rep
     test_join_map : 62.1697 µs/rep
test_array_library : 63.7088 µs/rep
    test_join_list : 112.021 µs/rep
test_join_iterator : 171.331 µs/rep
    test_naive_add : 286.632 µs/rep

Setup was CPython 3.8.2 (32-bit), Windows 10, i7-2600 3.4GHz

Interesting observations:

  • The "official" fastest answer (as reposted by Toni Ruža) is now out of date for Python 3, but once fixed is still basically tied for second place
  • Joining a mapped sequence is almost twice as fast as a list comprehension
  • The list comprehension is faster than its non-list counterpart

Code to reproduce is here:

import array, string, timeit, random
from collections import namedtuple

# Thomas Wouters (https://stackoverflow.com/a/180615/13528444)
def test_join_iterator(seq):
    return ''.join(chr(c) for c in seq)

# community wiki (https://stackoverflow.com/a/181057/13528444)
def test_join_map(seq):
    return ''.join(map(chr, seq))

# Thomas Vander Stichele (https://stackoverflow.com/a/180617/13528444)
def test_join_list(seq):
    return ''.join([chr(c) for c in seq])

# Toni Ruža (https://stackoverflow.com/a/184708/13528444)
# Also from https://www.python.org/doc/essays/list2str/
def test_array_library(seq):
    return array.array('b', seq).tobytes().decode()  # Updated from tostring() for Python 3

# David White (https://stackoverflow.com/a/34246694/13528444)
def test_naive_add(seq):
    output = ''
    for c in seq:
        output += chr(c)
    return output

# Timo Herngreen (https://stackoverflow.com/a/55509509/13528444)
def test_bytes_decode(seq):
    return bytes(seq).decode()

RESULT = ''.join(random.choices(string.printable, None, k=1000))
INT_SEQ = [ord(c) for c in RESULT]
REPS=10000

if __name__ == '__main__':
    tests = {
        name: test
        for (name, test) in globals().items()
        if name.startswith('test_')
    }

    Result = namedtuple('Result', ['name', 'passed', 'time', 'reps'])
    results = [
        Result(
            name=name,
            passed=test(INT_SEQ) == RESULT,
            time=timeit.Timer(
                stmt=f'{name}(INT_SEQ)',
                setup=f'from __main__ import INT_SEQ, {name}'
                ).timeit(REPS) / REPS,
            reps=REPS)
        for name, test in tests.items()
    ]
    results.sort(key=lambda r: r.time if r.passed else float('inf'))

    def seconds_per_rep(secs):
        (unit, amount) = (
            ('s', secs) if secs > 1
            else ('ms', secs * 10 ** 3) if secs > (10 ** -3)
            else ('µs', secs * 10 ** 6) if secs > (10 ** -6)
            else ('ns', secs * 10 ** 9))
        return f'{amount:.6} {unit}/rep'

    max_name_length = max(len(name) for name in tests)
    for r in results:
        print(
            r.name.rjust(max_name_length),
            ':',
            'failed' if not r.passed else seconds_per_rep(r.time))

Question = [67, 121, 98, 101, 114, 71, 105, 114, 108, 122]
print(''.join(chr(number) for number in Question))

Same basic solution as others, but I personally prefer to use map instead of the list comprehension:


>>> L = [104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100]
>>> ''.join(map(chr,L))
'hello, world'

import array
def f7(list):
    return array.array('B', list).tostring()

from Python Patterns - An Optimization Anecdote


def working_ascii():
    """
        G    r   e    e    t    i     n   g    s    !
        71, 114, 101, 101, 116, 105, 110, 103, 115, 33
    """

    hello = [71, 114, 101, 101, 116, 105, 110, 103, 115, 33]
    pmsg = ''.join(chr(i) for i in hello)
    print(pmsg)

    for i in range(33, 256):
        print(" ascii: {0} char: {1}".format(i, chr(i)))

working_ascii()

l = [83, 84, 65, 67, 75]

s = "".join([chr(c) for c in l])

print s

Perhaps not as Pyhtonic a solution, but easier to read for noobs like me:

charlist = [34, 38, 49, 67, 89, 45, 103, 105, 119, 125]
mystring = ""
for char in charlist:
    mystring = mystring + chr(char)
print mystring

I've timed the existing answers. Code to reproduce is below. TLDR is that bytes(seq).decode() is by far the fastest. Results here:

 test_bytes_decode : 12.8046 µs/rep
     test_join_map : 62.1697 µs/rep
test_array_library : 63.7088 µs/rep
    test_join_list : 112.021 µs/rep
test_join_iterator : 171.331 µs/rep
    test_naive_add : 286.632 µs/rep

Setup was CPython 3.8.2 (32-bit), Windows 10, i7-2600 3.4GHz

Interesting observations:

  • The "official" fastest answer (as reposted by Toni Ruža) is now out of date for Python 3, but once fixed is still basically tied for second place
  • Joining a mapped sequence is almost twice as fast as a list comprehension
  • The list comprehension is faster than its non-list counterpart

Code to reproduce is here:

import array, string, timeit, random
from collections import namedtuple

# Thomas Wouters (https://stackoverflow.com/a/180615/13528444)
def test_join_iterator(seq):
    return ''.join(chr(c) for c in seq)

# community wiki (https://stackoverflow.com/a/181057/13528444)
def test_join_map(seq):
    return ''.join(map(chr, seq))

# Thomas Vander Stichele (https://stackoverflow.com/a/180617/13528444)
def test_join_list(seq):
    return ''.join([chr(c) for c in seq])

# Toni Ruža (https://stackoverflow.com/a/184708/13528444)
# Also from https://www.python.org/doc/essays/list2str/
def test_array_library(seq):
    return array.array('b', seq).tobytes().decode()  # Updated from tostring() for Python 3

# David White (https://stackoverflow.com/a/34246694/13528444)
def test_naive_add(seq):
    output = ''
    for c in seq:
        output += chr(c)
    return output

# Timo Herngreen (https://stackoverflow.com/a/55509509/13528444)
def test_bytes_decode(seq):
    return bytes(seq).decode()

RESULT = ''.join(random.choices(string.printable, None, k=1000))
INT_SEQ = [ord(c) for c in RESULT]
REPS=10000

if __name__ == '__main__':
    tests = {
        name: test
        for (name, test) in globals().items()
        if name.startswith('test_')
    }

    Result = namedtuple('Result', ['name', 'passed', 'time', 'reps'])
    results = [
        Result(
            name=name,
            passed=test(INT_SEQ) == RESULT,
            time=timeit.Timer(
                stmt=f'{name}(INT_SEQ)',
                setup=f'from __main__ import INT_SEQ, {name}'
                ).timeit(REPS) / REPS,
            reps=REPS)
        for name, test in tests.items()
    ]
    results.sort(key=lambda r: r.time if r.passed else float('inf'))

    def seconds_per_rep(secs):
        (unit, amount) = (
            ('s', secs) if secs > 1
            else ('ms', secs * 10 ** 3) if secs > (10 ** -3)
            else ('µs', secs * 10 ** 6) if secs > (10 ** -6)
            else ('ns', secs * 10 ** 9))
        return f'{amount:.6} {unit}/rep'

    max_name_length = max(len(name) for name in tests)
    for r in results:
        print(
            r.name.rjust(max_name_length),
            ':',
            'failed' if not r.passed else seconds_per_rep(r.time))

import array
def f7(list):
    return array.array('B', list).tostring()

from Python Patterns - An Optimization Anecdote


Same basic solution as others, but I personally prefer to use map instead of the list comprehension:


>>> L = [104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100]
>>> ''.join(map(chr,L))
'hello, world'

You can use bytes(list).decode() to do this - and list(string.encode()) to get the values back.


Perhaps not as Pyhtonic a solution, but easier to read for noobs like me:

charlist = [34, 38, 49, 67, 89, 45, 103, 105, 119, 125]
mystring = ""
for char in charlist:
    mystring = mystring + chr(char)
print mystring

Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to string

How to split a string in two and store it in a field String method cannot be found in a main class method Kotlin - How to correctly concatenate a String Replacing a character from a certain index Remove quotes from String in Python Detect whether a Python string is a number or a letter How does String substring work in Swift How does String.Index work in Swift swift 3.0 Data to String? How to parse JSON string in Typescript

Examples related to ascii

Detect whether a Python string is a number or a letter Is there any ASCII character for <br>? UnicodeEncodeError: 'ascii' codec can't encode character at special name Replace non-ASCII characters with a single space Convert ascii value to char What's the difference between ASCII and Unicode? Invisible characters - ASCII How To Convert A Number To an ASCII Character? Convert ascii char[] to hexadecimal char[] in C Convert character to ASCII numeric value in java