Listenformatierung

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
gorba
User
Beiträge: 100
Registriert: Freitag 28. Juli 2006, 14:58

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?
pr0stAta
User
Beiträge: 271
Registriert: Freitag 17. September 2004, 11:49
Wohnort: Bremen

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
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

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 = ''
gorba
User
Beiträge: 100
Registriert: Freitag 28. Juli 2006, 14:58

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
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

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
gorba
User
Beiträge: 100
Registriert: Freitag 28. Juli 2006, 14:58

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
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.
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

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
gorba
User
Beiträge: 100
Registriert: Freitag 28. Juli 2006, 14:58

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.
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.
gorba
User
Beiträge: 100
Registriert: Freitag 28. Juli 2006, 14:58

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..
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.
gorba
User
Beiträge: 100
Registriert: Freitag 28. Juli 2006, 14:58

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
Antworten