Seite 1 von 1
mehrdimensionale Listen
Verfasst: Donnerstag 31. Mai 2007, 15:37
von ronnyno
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
Re: mehrdimensionale Listen
Verfasst: Donnerstag 31. Mai 2007, 15:46
von schlangenbeschwörer
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.
Verfasst: Donnerstag 31. Mai 2007, 15:46
von Sr4l
Am besten Code posten.
Verfasst: Donnerstag 31. Mai 2007, 16:04
von ronnyno
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])
Verfasst: Donnerstag 31. Mai 2007, 16:12
von schlangenbeschwörer
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.
Verfasst: Donnerstag 31. Mai 2007, 16:16
von veers
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.
Verfasst: Donnerstag 31. Mai 2007, 16:17
von Sr4l
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
Verfasst: Donnerstag 31. Mai 2007, 16:27
von ronnyno
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)
Verfasst: Donnerstag 31. Mai 2007, 16:30
von veers
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:
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:
List2String:
Verfasst: Donnerstag 31. Mai 2007, 16:34
von ronnyno
das stand leider in keinem von den tuts die ich gelesen habe ... ( oder ich habs ueberlesen ... )
werd damit jetzt mal ein wenig rumexperimentieren
vielen dank euch allen !
Verfasst: Donnerstag 31. Mai 2007, 16:36
von Rebecca
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.
Wenn du wirklich einen Buchstaben nach Index ersetzen willst, faellt mir gerade nur sowas ein:
EDIT: Ah ja, der Vorschlag von veer ist natuerlich schoener.
Verfasst: Donnerstag 31. Mai 2007, 16:38
von encbladexp
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
zugreifen. Aber
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
Verfasst: Donnerstag 31. Mai 2007, 16:52
von veers
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.
Verfasst: Donnerstag 31. Mai 2007, 16:59
von ronnyno
--- hat sich erledigt ---
Verfasst: Donnerstag 31. Mai 2007, 17:00
von Sr4l
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:
habs aber so gelassen.
Verfasst: Donnerstag 31. Mai 2007, 17:00
von veers
ronnyno hat geschrieben:also man hat a='hello' und will haben liste=['h','e','l','l','o']
veers hat geschrieben:
String2List:
Verfasst: Donnerstag 31. Mai 2007, 17:08
von ronnyno
prima jetzt laeufts einwandfrei !
und wieder viel dazugelernt
Verfasst: Donnerstag 31. Mai 2007, 17:46
von 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.
Verfasst: Donnerstag 31. Mai 2007, 19:36
von veers
Code: Alles auswählen
Ix = MutableString("Foobar")
x[1]
>>>> 'o'
x[1] = '0'
x
>>>> 'F0obar'
Gibt also auch Mutable Strings