Seite 1 von 1
Listenformatierung
Verfasst: Mittwoch 23. August 2006, 14:56
von gorba
Hallo
Folgendes Problem
Ich habe 2 Variabeln, wenn ich die einte ausgebe sieht sie so aus:
[33, 33, 33, 33, 33, 33, 33, 33, 33]
und die andere so:
22222222
Kann ich die 2te Variable nachträglich noch umwandeln, damit sie auch eine "Liste" ist? Damit sie nacher so aussehen würde:
[22, 22, 22, 22]
Funktioniert das irgendwie?
Verfasst: Mittwoch 23. August 2006, 15:20
von pr0stAta
Es wird bestimmt gleich eine viel schönere
Lösung als meine geben aber sie sollte funktionieren ^^
Code: Alles auswählen
zahlen_string = "222222"
liste, cnt = [], 0
for char in zahlen_string:
if cnt % 2 == 0:
liste.append(char + char)
cnt += 1
Gruss prosta
Verfasst: Mittwoch 23. August 2006, 15:23
von Masaru
auch nicht so hübsch, aber ebenso einfach:
Code: Alles auswählen
>>> base = str(2222222)
>>> while base:
... if len(base) >= 2:
... result.append(int(base[:2]))
... base = base[2:]
... else:
... result.append(int(base))
... base = ''
Verfasst: Mittwoch 23. August 2006, 15:41
von gorba
funktioniert gut. Ist das nun eine Liste von strings? Schliesse ich aus den '' um die werte. Kann man auch eine Liste von words machen? Also anstatt
['22', '22', '22', '22']
sowas:
[22, 22, 22, 22]
Da ich Bilddaten binär in meiner Variable stehen habe, und diese irgendwie in eine Liste müssen bin ich echt am ende. int geht nicht, da binärdaten gewisse Zeichen drin haben, die nicht als int erkannt werden:
Code: Alles auswählen
File "picSplit.py", line 49, in splitPic
result.append(int(base[:2]))
ValueError: invalid literal for int(): 1ÿ
>Exit code: 1
Verfasst: Mittwoch 23. August 2006, 16:07
von rayo
Hi
Warum in einen String wandeln?
Code: Alles auswählen
def int2list(number, chunk_size):
l = []
while number > 0:
l.insert(0,number%(10**chunk_size))
number = number/(10**chunk_size)
return l
print int2list(222222,2)
Gruss
*edit* hmm hast du denn binär daten die du zu jeweils shorts (2Byte) in eine liste speichern willst? dann ist das modul struct was für dich
Verfasst: Mittwoch 23. August 2006, 16:15
von gorba
rayo hat geschrieben:Hi
Warum in einen String wandeln?
Code: Alles auswählen
def int2list(number, chunk_size):
l = []
while number > 0:
l.insert(0,number%(10**chunk_size))
number = number/(10**chunk_size)
return l
print int2list(222222,2)
Gruss
Hi, gibt bei mir die Fehlermeldung:
Code: Alles auswählen
File "picSplit.py", line 38, in int2list
l.insert(0,number%(10**chunk_size))
ValueError: unsupported format character '&' (0x26) at index 283
Verfasst: Mittwoch 23. August 2006, 16:18
von BlackJack
Oder das Modul `array`. Am bestren erzählt gorba uns mal was er machen möchte. Und zwar als Problembeschreibung und nicht aus der Sicht einer Lösung.
Verfasst: Mittwoch 23. August 2006, 16:19
von rayo
Hi
zeig mal dein Code, was genau willst du umwandeln?
Wenn es binär-Daten sind (anscheinend Bilder) musst du mit Struct umwandeln
Code: Alles auswählen
def bin2list(data, little_endian=True):
l = []
if little_endian:
fmt = '%dH' % (len(data)/2)
else:
fmt = '>%dH' % (len(data)/2)
return struct.unpack(fmt,data)
print bin2list("\x01\x00\x00\xFF\x22\x22") #(1, 65280, 8738)
print bin2list("\x01\x00", False) #(256,)
Gruss
Verfasst: Donnerstag 24. August 2006, 07:55
von gorba
ok, ich muss bilddaten an ein modul übergeben, dass nur listen akzeptiert:
ich lese also Bilddaten aus (zerstückelt in blöcke):
Code: Alles auswählen
f = file('picture.jpg', 'rb')
result = list(iter(lambda: f.read(500), ""))
Diese blöcke hole ich mir später im Program wieder (speichere mal einen in tdat) und will sie nun senden, allerdings müssen sie in ein "Frame" gepackt werden, und das übernimmt ein fremdes Modul das ich nicht ändern darf:
Code: Alles auswählen
print '- Now sending the Block %d -' % AcBlock
SEFD.sendFrame(SerialFrame(cmd=ROUTE_CMD,data = tdat),debug = 0)
Die Funktion im dem Modul sieht dann so aus:
Code: Alles auswählen
def __init__(self,cmd = 0, length = 0, data = [], startSign = SERIAL_FRAME_START_SIGN, endSign = SERIAL_FRAME_END_SIGN, asStr = []):
""" fills a frame that can be sent to the serial port """
if not length:
length = (len(data)+2) * 2
self.cmd = cmd
self.length = length
self.data = data
self.startSign = startSign
self.endSign = endSign
if asStr:
self.dataStr = asStr
self.dataString = self.fill(cmd,length,data,startSign,endSign)
def fill(self,cmd = 0, length = 0, data = [], startSign = SERIAL_FRAME_START_SIGN, endSign = SERIAL_FRAME_END_SIGN):
if not length:
length = (len(data)+2) * 2
# pack start, command and length info
temp = struct.pack('>HHH',startSign,length,cmd)
# now the data
for word in data:
temp = temp + struct.pack(">H",word)
for i in data:
i = i ^ i
#~ print i
self.checksum = i
temp = temp + struct.pack(">H",self.checksum);
# and the end
temp = temp + struct.pack(">H",endSign)
return temp
Ich kann die Funktion sendFrame(SerialFrame()) nur ansprechen, wenn ich ihm als Data eine Liste übergebe von der Art:
bla = [22, 22, 22, 22]
Und meine Bilddaten die da übergeben werden müssten sind nicht in dieser Form.
Verfasst: Donnerstag 24. August 2006, 08:18
von BlackJack
Was genau muss die Liste denn enthalten? Zahlen nehme ich an!? Die Daten als Bytewerte oder als Word-Werte? Also bei 500 Bytes an Daten, willst Du dann 500 Einträge zwischen 0 und 255 in der Liste haben oder 250 Einträge zwischen 0 und 65535?
In beiden Fällen lohnt sich ein Blick auf's `array` Modul.
Edit: Ich hätte mal den Quelltext lesen sollen.
Was Du suchst ist definitiv das `array`-Modul:
Code: Alles auswählen
In [17]: data = 'abcdef'
In [18]: a = array.array('H')
In [19]: a.fromstring(data)
In [20]: a
Out[20]: array('H', [25185, 25699, 26213])
Das `array` Objekt müsstest Du dann auch direkt übergeben können.
Verfasst: Donnerstag 24. August 2006, 09:05
von gorba
BlackJack hat geschrieben:Was genau muss die Liste denn enthalten? Zahlen nehme ich an!? Die Daten als Bytewerte oder als Word-Werte? Also bei 500 Bytes an Daten, willst Du dann 500 Einträge zwischen 0 und 255 in der Liste haben oder 250 Einträge zwischen 0 und 65535?
In beiden Fällen lohnt sich ein Blick auf's `array` Modul.
Edit: Ich hätte mal den Quelltext lesen sollen.
Was Du suchst ist definitiv das `array`-Modul:
Code: Alles auswählen
In [17]: data = 'abcdef'
In [18]: a = array.array('H')
In [19]: a.fromstring(data)
In [20]: a
Out[20]: array('H', [25185, 25699, 26213])
Das `array` Objekt müsstest Du dann auch direkt übergeben können.
Das habe ich auch schon versucht und wider verworfen, nachdem ich bei:
Code: Alles auswählen
File "picSplit.py", line 46, in getArray
a.fromstring(data)
ValueError: string length not a multiple of item size
angestanden bin..
Verfasst: Donnerstag 24. August 2006, 09:50
von BlackJack
gorba hat geschrieben:Das habe ich auch schon versucht und wider verworfen, nachdem ich bei:
Code: Alles auswählen
File "picSplit.py", line 46, in getArray
a.fromstring(data)
ValueError: string length not a multiple of item size
angestanden bin..
Mit dem Problem musst Du aber sowieso irgendwie umgehen, egal ob Du `array` oder etwas anderes benutzt. Die Sendemethode erwartet offensichtlich 16-Bit-Werte, also
muss die Anzahl der Bytes der zu sendenden Daten durch zwei teilbar sein.
Verfasst: Donnerstag 24. August 2006, 09:51
von gorba
Das sollte klappen:
Code: Alles auswählen
def dataConvert(testData, size):
txData = []
for i in range(0,size-1,2):
txData.append( (ord(testData[i])<<8) + ord(testData[i+1]))
if len(txData) % 2 != 0: txData.append(0)
return txData