mehrdimensionale Listen

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
ronnyno
User
Beiträge: 12
Registriert: Dienstag 29. Mai 2007, 21:35

Hi !
Ich will einfach innerhalb einer Schleife ein Element einer zwei dimensionalen Liste durch das entsprechende einer anderen ersetzen, aber ich bekomme immer einen Fehler:

Traceback (most recent call last):
File "C:\Programme\Python25\renamer.py", line 27, in <module>
filelist[0]=filelistsave[0]
TypeError: 'str' object does not support item assignment


Hilfe !!!!!!! :-) Viele Gruesse, Ronny
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Hi!
Die musst du lesen:
ronnynos Fehlermeldung hat geschrieben: Traceback (most recent call last):
File "C:\Programme\Python25\renamer.py", line 27, in <module>
filelist[0]=filelistsave[0]
TypeError: 'str' object does not support item assignment

Die letzte Zeile sagts doch: ´´filelist´´ (oder ´´filelist) ist keine Liste sondern ein String.
Für genauere Fehleranalyse und -behebung wär auch (mehr) Code nötig.

Gruß, jj

edit: der Fehler könnte natürlich auch von ´´filelistsave´´kommen.
Zuletzt geändert von schlangenbeschwörer am Donnerstag 31. Mai 2007, 15:53, insgesamt 1-mal geändert.
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

Am besten Code posten.
ronnyno
User
Beiträge: 12
Registriert: Dienstag 29. Mai 2007, 21:35

ich will eigentlich nur die '_' in den Dateinamen entfernen, den Anfangsbuchstaben gross schreiben, sowie den Buchstaben nach dem '-'.
Dazu wollte ich eigentlich, wie im ein dimensionalen, einfach die Werte der Liste veraendern. Das ging in 2d aber irgendwie nicht. Hab dann die funktion replace gefunden, damit gings dann, damit ist es aber viel zu umstaendlich und sie macht auch nicht genau das, was ich will.

filelist= os.listdir(verz)
filelistsave=filelist

for i in range(0,len(filelist)):
filelist=filelist.replace('_',' ')
filelistsave=filelistsave.replace(filelistsave[0],string.upper(filelistsave[0]))
filelist[0]=filelistsave[0]
for j in range(0,len(filelist)):
if filelistsave[j]=='-':
filelistsave[i]=filelistsave[i].replace(filelistsave[i][j+2],string.upper(filelistsave[i][j+2]))
filelist[i][j+2]=filelistsave[i][j+2]

print os.listdir(verz)[i]+' -> '+filelist[i]
os.rename(verz+os.listdir(verz)[i],verz+filelist[i])
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

1. So kann man den Code fast nicht lesen. -> Setz ihn bitte in [ (/)code ]-Tags.
2. Anstatt die Liste zu kopieren und dann irgedwie zu ändern, kannst du doch einfach in einer Schleife über die Ausgangsliste iritieren, jeden Wert wie gewünscht verändern und dann in einer neuen Liste speichern.
Das ist einfacher, lesbarer/verständlicher und ich denk auch mal weniger problematisch.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Hinweis: Dir ist bewusst das du so:
filelistsave = filelist
Keine Kopie von filelist anfertigst sondern lediglich die Referenz kopierst?
Tipp: Kopieren geht so: filelistsave = list(filelist)
Tipp: range(0, N) == range(N)
Tipp: Lies dir mal den PEP 8 durch. So wird dein Code lesbarer.

Code: Alles auswählen

filelist = os.listdir(verz)
filelistsave = filelist

for i in range(0, len(filelist)):
	filelist[i] = filelist[i].replace('_', ' ')
    filelistsave[i] = filelistsave[i].replace(filelistsave[i][0], string.upper(filelistsave[i][0]))
    filelist[i][0] = filelistsave[i][0]
    for j in range(0, len(filelist[i])):
		if filelistsave[i][j] == '-':
			filelistsave[i] = filelistsave[i].replace(filelistsave[i][j + 2], string.upper(filelistsave[i][j + 2]))
            filelist[i][j + 2] = filelistsave[i][j + 2]
                        
        print os.listdir(verz)[i] + ' -> ' + filelist[i]
        os.rename(verz + os.listdir(verz)[i], verz + filelist[i])
So lässt sich das ganze zumindest schonmal besser lesen.
Zuletzt geändert von veers am Donnerstag 31. Mai 2007, 16:24, insgesamt 3-mal geändert.
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

ronnyno hat geschrieben:

Code: Alles auswählen

        filelist= os.listdir(verz)
        filelistsave=filelist
        
        for i in range(0,len(filelist)):
            filelist[i]=filelist[i].replace('_',' ')
            filelistsave[i]=filelistsave[i].replace(filelistsave[i][0],string.upper(filelistsave[i][0]))
            filelist[i][0]=filelistsave[i][0]
            for j in range(0,len(filelist[i])):
                if filelistsave[i][j]=='-':
                    filelistsave[i]=filelistsave[i].replace(filelistsave[i][j+2],string.upper(filelistsave[i][j+2]))
                    filelist[i][j+2]=filelistsave[i][j+2]
                        
            print os.listdir(verz)[i]+' -> '+filelist[i]
            os.rename(verz+os.listdir(verz)[i],verz+filelist[i])
Dein Problem ist einfach. Du darfst nur in die zweite for-Schleife gehen wenn diese eine Liste ist. Wenn es ein String ist musst du diesen Punkt überspringen.

**edit**
oich rewrite mal
Zuletzt geändert von Sr4l am Donnerstag 31. Mai 2007, 16:32, insgesamt 1-mal geändert.
ronnyno
User
Beiträge: 12
Registriert: Dienstag 29. Mai 2007, 21:35

da ich noch absoluter Anfaenger bin, ist der restliche code eher verwirrend, deshalb habe ich ihn zuerst nicht gepostet.

ok, das problem mal einfacher:

liste=['hallo','welt']
liste[0][0]='a'
print liste

Warum funktioniert das nicht ?
( sollte dem Problem oben entsprechen, erhalte die gleiche Fehlermeldung)
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

ronnyno hat geschrieben:da ich noch absoluter Anfaenger bin, ist der restliche code eher verwirrend, deshalb habe ich ihn zuerst nicht gepostet.

ok, das problem mal einfacher:

liste=['hallo','welt']
liste[0][0]='a'
print liste

Warum funktioniert das nicht ?
( sollte dem Problem oben entsprechen, erhalte die gleiche Fehlermeldung)
Weil Strings in Python imutable sind. Das heist du kannst sie nicht verändern ;)
Gehen würde:

Code: Alles auswählen

liste[0] = 'a' + liste[0][1:]
Falls du aber mal nicht das erste Element verändern willst sondern den String wirklich wie eine Liste behandeln willst: Mach draus einfach eine:

String2List:

Code: Alles auswählen

list("hello")
List2String:

Code: Alles auswählen

"".join(['h', 'e', 'l', 'l', 'o'])
ronnyno
User
Beiträge: 12
Registriert: Dienstag 29. Mai 2007, 21:35

das stand leider in keinem von den tuts die ich gelesen habe ... ( oder ich habs ueberlesen ... )

werd damit jetzt mal ein wenig rumexperimentieren :D

vielen dank euch allen !
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Erstmal lege ich dir das hier ans Herz: http://www.python-forum.de/faq.php#21

Dein Problem ist, dass man Strings nicht veraendern kann.

Code: Alles auswählen

>>> a = "hallo"
>>> a[0] = "n"
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object does not support item assignment
Du hast eben keine Liste von Listen, sondern eine Liste von Strings. Wenn du bestimmte Zeichen in Strings durch andere ersetzen willst, ist "replace" etwas fuer dich.

Code: Alles auswählen

>>> a.replace("l", "n")
'hanno'
>>>
Wenn du wirklich einen Buchstaben nach Index ersetzen willst, faellt mir gerade nur sowas ein:

Code: Alles auswählen

>>> "n%s" % a[1:]
'nallo'
EDIT: Ah ja, der Vorschlag von veer ist natuerlich schoener. :)
encbladexp
User
Beiträge: 61
Registriert: Freitag 7. März 2003, 19:28
Kontaktdaten:

Und nochmal: Für Code immer eine Code-Block benutzen (deswegen heist der so!).

Warum sollte das was du versuchst auch funktionieren? Du hast eine Stinknormale Liste, auf die kannste mit

Code: Alles auswählen

liste[0]
zugreifen. Aber

Code: Alles auswählen

liste[0][0]
kann net gehen, weil ja das 0. Element der String hallo ist, und eben keine liste...

Eine deutlich bessere Lösung wurde ja schon weiter oben vorgeschlagen!

mfg Betz Stefan
edit: An dem das Stings nicht veränderbar sind ist auch was dran, hab den Code leider nicht so genau gelesen :-(
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Wieso sind Strings eigentlich immutable?

Was ich im Web gefunden habe ist das Strings nicht wachsen können weil das nicht explizit genug wäre. Das ist mir ja soweit klar. Wieso man einzelne Characters nicht ändern kann nicht.

Edit:
http://www.thescripts.com/forum/thread34919.html
Not being able to use strings as dictionary keys would kind of suck :)
Hm damit hat er wohl recht.
Zuletzt geändert von veers am Donnerstag 31. Mai 2007, 16:59, insgesamt 1-mal geändert.
ronnyno
User
Beiträge: 12
Registriert: Dienstag 29. Mai 2007, 21:35

--- hat sich erledigt ---
Zuletzt geändert von ronnyno am Donnerstag 31. Mai 2007, 17:01, insgesamt 1-mal geändert.
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

natürlich geht [0][0], man kann den Index nur nicht verändern ;-)
Man könnten den String ja auch in ein Liste spliten jende Buchstaben aber naja hier meine Lösung:

Code: Alles auswählen

#!/usr/bin/python
#*~* coding: latin-1 *~*
import os
import string

filelist= os.listdir('/home/sr4l/test')
#filelistsave=filelist  #brauch ich nicht ^^
	
for i in range(len(filelist)):
	filelist[i]=filelist[i].replace('_',' ')
	filelist[i]= "".join([string.upper(filelist[i][0]),filelist[i][1:]])
	for j in range(len(filelist[i])-1):
			if filelist[i][j] == '-':
				filelist[i] = "".join([filelist[i][:j+1],string.upper(filelist[i][j+1]),filelist[i][j+2:]])

	#print os.listdir(verz)[i]+' -> '+filelist[i]
	#os.rename(verz+os.listdir(verz)[i],verz+filelist[i])
	print filelist
hätte ich den code geschreiben hätte ich filelist nur fl genannt (man ist das ein langes wort ;-) )
ach und PS das modul string braucht man kaum.
upper ist ein builtin und kann einfach per:

Code: Alles auswählen

>>> "lol".upper()
'LOL'
habs aber so gelassen.
Zuletzt geändert von Sr4l am Donnerstag 31. Mai 2007, 17:02, insgesamt 1-mal geändert.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

ronnyno hat geschrieben:also man hat a='hello' und will haben liste=['h','e','l','l','o']
veers hat geschrieben: String2List:

Code: Alles auswählen

list("hello")
ronnyno
User
Beiträge: 12
Registriert: Dienstag 29. Mai 2007, 21:35

prima jetzt laeufts einwandfrei !
und wieder viel dazugelernt :-)
BlackJack

Alternativlösung ohne die ganze Indexerei:

Code: Alles auswählen

import re

def main():
    filenames = ['foo - bar - baz']
    dash_re = re.compile(r'(- )(.)')
    result = list()
    for filename in filenames:
        filename = filename.replace('_', ' ').capitalize()
        filename = dash_re.sub(lambda m: m.group(1) + m.group(2).upper(),
                               filename)
        result.append(filename)
    print result
Mal vom regulären Ausdruck abgesehen etwas lesbarer.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Code: Alles auswählen

Ix = MutableString("Foobar")
x[1]
>>>> 'o'
x[1] = '0'
x
>>>> 'F0obar'
Gibt also auch Mutable Strings ;)
Antworten