array - Liste bestehend aus Elementen nicht änderbarer Daten
Link
zu Doug Hellmanns Original Artikel vom 09. November 2008
| Zweck: |
Effizienter Umgang mit Sequenzen, die aus unveränderlichen Elementen bestehen |
| Python: |
ab 1.4 |
Das array Modul definiert eine Listenstruktur die große Ähnlichkeit
mit einer list hat, außer das alle Elemente vom gleichen Datentyp sein müssen.
Die unterstützten Datentypen sind in der Standard Library Dokumentation
zu finden. Sie sind alle numerisch beziehungsweise unveränderliche Datentypen wie zum Beispiel bytes.
Array Initialisierung
Ein array wird durch die Übergabe eines Parameters, welcher den Datentyp definiert, initialisiert und
durch die optionalen Übergabe einer Liste.
import array
import binascii
s = 'This is the array.'
a = array.array('c', s)
print 'Als string:', s
print 'Als array :', a
print 'Als Hex-Zahl :', binascii.hexlify(a)
In diesem Beispiel erwartet das array eine Sequenz von Bytes und es wird mit einem einfachen String initialisiert.
$ python array_string.py
Als string: This is the array.
Als array : array('c', [84, 104, 105, 115, 32, 105, 115,32, 116, 104, 101, 32, 97, 114, 114, 97, 121, 46])
Als Hex-Zahl : 54686973206973207468652061727261792e
Manipulation von Arrays
Ein array kann wie jede andere Python Sequenz erweitert und manipuliert werden.
import array
a = array.array('i', xrange(5))
print 'Initialwert :', a
a.extend(xrange(5))
print 'Erweitert:', a
print 'Slice :', a[3:6]
print 'Iterator:', list(enumerate(a))
$ python array_sequence.py
Initialwert : array('i', [0, 1, 2, 3, 4])
Erweitert: array('i', [0, 1, 2, 3, 4, 0, 1, 2, 3, 4])
Slice : array('i', [3, 4, 0])
Iterator: [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 0), (6, 1), (7, 2), (8, 3), (9, 4)]
Arrays und Dateien
Der Inhalt von Arrays kann aus Dateien gelesen und geschrieben werden.
Hierzu werden eingebaute Methoden verwendet, die speziell für diesen Zweck entwickelt wurden.
import array
import binascii
import tempfile
a = array.array('i', xrange(5))
print 'A1:', a
# Schreibt das Array aus Zahlen in eine Datei
output = tempfile.NamedTemporaryFile()
a.tofile(output.file) # must pass an *actual* file
output.flush()
# Liest die Rohdaten
input = open(output.name, 'rb')
raw_data = input.read()
print 'Rohdaten:', binascii.hexlify(raw_data)
# Liest die Daten in ein array
input.seek(0)
a2 = array.array('i')
a2.fromfile(input, len(a))
print 'A2:', a2
Dieses Beispiel illustriert das Lesen der Rohdaten direkt aus der Binärdatei, anstatt sie in ein array einzulesen und die
Bytes dann in die passenden Datentypen zu konvertieren.
$ python array_file.py
A1: array('i', [0, 1, 2, 3, 4])
Rohdaten: 0000000001000000020000000300000004000000
A2: array('i', [0, 1, 2, 3, 4])
Alternative Byte-Reihenfolge
Wenn die Daten im Array nicht in der natürlichen Byte-Reihenfolge vorliegen oder getauscht werden müssen ehe sie,
für ein anderes System mit abweichender Byte-Reihenfolge, in eine Datei geschrieben werden, so ist es einfach ein
vollständiges Array zu konvertieren ohne über die einzelnen Elemente mittels Python zu iterieren.
import array
import binascii
def to_hex(a):
chars_per_item = a.itemsize * 2 # 2 hexadezimale Zahlen
hex_version = binascii.hexlify(a)
num_chunks = len(hex_version) / chars_per_item
for i in xrange(num_chunks):
start = i*chars_per_item
end = start + chars_per_item
yield hex_version[start:end]
a1 = array.array('i', xrange(5))
a2 = array.array('i', xrange(5))
a2.byteswap()
fmt = '%10s %10s %10s %10s'
print fmt % ('A1 hex', 'A1', 'A2 hex', 'A2')
print fmt % (('-' * 10,) * 4)
for values in zip(to_hex(a1), a1, to_hex(a2), a2):
print fmt % values
$ python array_byteswap.py
A1 hex A1 A2 hex A2
---------- ---------- ---------- ----------
00000000 0 00000000 0
01000000 1 00000001 16777216
02000000 2 00000002 33554432
03000000 3 00000003 50331648
04000000 4 00000004 67108864