Wie konvertiere ich eine Liste von ASCII-Werten in eine Zeichenfolge in Python?


73

Ich habe eine Liste in einem Python-Programm, die eine Reihe von Zahlen enthält, die selbst ASCII-Werte sind. Wie konvertiere ich dies in eine "normale" Zeichenfolge, die ich auf dem Bildschirm wiedergeben kann?

Antworten:


134

Sie suchen wahrscheinlich nach 'chr ()':

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

8
Ich wette, Sie haben diese Liste L mit[ord(x) for x in 'hello, world']
zapstar

chars = [chr(i) for i in range(97, 97 + 26)]
FindOutIslamNow

22

Gleiche Grundlösung wie andere, aber ich persönlich bevorzuge die Verwendung der Karte anstelle des Listenverständnisses:


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



4

Vielleicht nicht als Pyhtonic eine Lösung, aber für Noobs wie mich leichter zu lesen:

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

2

Sie können dies verwenden bytes(list).decode(), list(string.encode())um die Werte zurückzugewinnen.


2
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()

0

Ich habe die vorhandenen Antworten zeitlich festgelegt. Der zu reproduzierende Code ist unten. TLDR ist bytes(seq).decode()bei weitem das schnellste. Ergebnisse hier:

 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

Das Setup war CPython 3.8.2 (32-Bit), Windows 10, i7-2600 3.4GHz

Interessante Beobachtungen:

  • Die "offizielle" schnellste Antwort (wie von Toni Ruža erneut veröffentlicht) ist für Python 3 nicht mehr aktuell, aber sobald sie behoben ist, ist sie im Grunde immer noch für den zweiten Platz gebunden
  • Das Verbinden einer zugeordneten Sequenz ist fast doppelt so schnell wie das Verstehen einer Liste
  • Das Listenverständnis ist schneller als das Nicht-Listen-Gegenstück

Der zu reproduzierende Code ist hier:

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))

Schließen Sie auch die von Ihnen verwendete Python-Implementierung ein, da dies die Benchmark-Zahlen beeinflussen kann. So können Sie diese Informationen abrufen stackoverflow.com/a/14718168/12160191 .
Mutable Side Effect

@MutableSideEffect Fertig. Ich weiß sofort, dass es CPython ist, aber ich hatte keine Ahnung, dass Sie das programmgesteuert finden können
user13528444

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

1
Bitte beachten Sie, dass es beim Stapelüberlauf üblich ist, eine Erklärung anzugeben, warum der vorgeschlagene Ansatz die Frage beantwortet - insbesondere, wenn die Frage älter ist und bereits eine akzeptierte Antwort hat. Inwiefern unterscheidet sich dieser Vorschlag und warum sollte er anstelle einer vorhandenen Antwort verwendet werden?
Cindy Meister
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.