Seite 1 von 1

a.append(a[i]+a[j]) - eine Anfängerfrage

Verfasst: Mittwoch 4. Februar 2009, 23:36
von Tyrax
Hallo Gemeinde,

ich bin ein blutiger Programmier- und ibs. Python-Anfänger und habe ein kleines Skript geschrieben, das - wie zB bei der Fibonacci-Folge - ein neues Listenelement aus den beiden vorangegangenen erzeugt. Die Listeneinträge sind Ganzzahlen. Mit

a = [1, 1]
a.append(a+a[j])

klappt es aber nicht. Python interpretiert meine Liste

[1, 1]

als

[(1,), (1,)]

und produziert dementsprechend eine Liste von Tupeln. Was kann ich tun?

Danke und Grüße, Tyrax

P.S.: Ich poste auch gerne das ganze Skript, wenn's hilft.

Re: a.append(a[i]+a[j]) - eine Anfängerfrage

Verfasst: Mittwoch 4. Februar 2009, 23:49
von DasIch
Tyrax hat geschrieben:P.S.: Ich poste auch gerne das ganze Skript, wenn's hilft.
Würde es.

Verfasst: Donnerstag 5. Februar 2009, 00:29
von ms4py
Wenn deine Liste aus Tupeln mit einem Element besteht müsste das funktionieren:

Code: Alles auswählen

a.append((a[i][0]+a[j][0],))

Verfasst: Donnerstag 5. Februar 2009, 00:35
von BlackJack
@Tyrax: Ich sehe da kein Problem:

Code: Alles auswählen

In [5]: a = [1, 1]

In [6]: a.append(a[i] + a[j])

In [7]: a
Out[7]: [1, 1, 2]
Ich könnte mir vorstellen, dass das nicht funktioniert, wenn `i` und `j` nicht an die richtigen Werte gebunden sind, aber wie da *Tupel* heraus kommen können, verstehe ich absolut nicht.

Wobei man statt `i` und `j` hier auch Konstante Zahlen einsetzen kann. Sind ja immer die gleichen Werte, nämlich der Index für's vorletzte und für's vorvorletzte Element.

Verfasst: Donnerstag 5. Februar 2009, 01:04
von Tyrax
Hallo,

danke erstmal. Erstaunlicherweise habe ich den Fehler nun selbst gefunden. Ich hatte zwei verirrte Kommata (siehe Code), die aus der Eingabe von a0 und a1 Tupel gemacht haben. Ich hatte die Zeilen erst an anderer Stelle und sie dann kopiert - mit Kommata. Sowas kommt von sowas.

Code: Alles auswählen

print("""Dieses Programm berechnet die Fibonacci-Folge zu deinen Startwerten \n und gibt die Folge bis zu einem von dir gewählten Zähler an.\n""")
a0 = int(input("Geben sie das erste Element ihrer Fibonacci-Folge an: a0 =")) # Hier hatte ich ein Komma
a1 = int(input("Geben sie das zweite Element ihrer Fibonacci-Folge an: a1 =")) # Hier auch
n  = int(input("Bis zu welchem Folgenglied soll die Folge berechnet werden? n ="))
i = 0  #
liste = [a0 , a1] #
# Zunächst definiere ich die Funktion und sage welche Variable sie verwendet:
def Fibonaccischritt():
      global liste, i
      liste.append(liste[i] + liste[i+1])
      i = i + 1
      return liste  #i # Eine Funktion läuft unabhängig vom restlichen Programm.
#                        Werte, mit denen noch gearbeitet werden soll, müssen daher mit "return" gesondert ausgegeben werden.
while i < n:
  Fibonaccischritt()
print(liste)
Über Kommentare und Verbesserungsvorschläge freue ich mich jederzeit.

Aber wie gesagt, nun klappt's. Danke und Grüße, Tyrax

Verfasst: Donnerstag 5. Februar 2009, 07:10
von audax
Warum machst du "liste" global?
Und "i" kannst du dir dank negativer indexierung sparen.

Code: Alles auswählen

liste.append(liste[-2] + liste[-1])

Verfasst: Donnerstag 5. Februar 2009, 07:46
von BlackJack
Insbesondere stimmt der Kommentar mit dem "unabhängig" nicht, wenn man externe Objekte verändert. Für `liste` ist ``global`` sogar unnötig, weil das Objekt verändert wird, aber nicht der Name neu gebunden wird. Auf ``global`` sollte man so gut wie immer verzichten. Werte sollte Funktionen als Argumente betreten und als Rückgabewerte verlassen.

Wenn man die Anzahl der Schleifendurchläufe schon vor Eintritt in die Schleife kennt, verwendet man besser eine ``for``-Schleife. Dann spart man sich den expliziten Text, die Initialisierung des Zählers vor der Schleife und das manuelle hochzählen innerhalb der Schleife.

Verfasst: Donnerstag 5. Februar 2009, 09:56
von audax

Verfasst: Donnerstag 5. Februar 2009, 13:42
von Tyrax
Hallo audax und BlackJack,

danke für die Hinweise. Der Kommentar zu "return" sollte eigentlich nicht hier rein, aber so lerne ich immerhin was dazu.

@audax: Die negative Indizierung hatte ich nicht von Anfang an, daher das i. Ich benutze es aber auch noch für die while-Schleife. Wenn ich, wie BlackJack vorschlägt, eine for-Schleife nehme, kann ich das i aber tatsächlich rausschmeißen. Deinen Link muss ich noch genauer angucken.

Grüße, Tyrax

Verfasst: Donnerstag 5. Februar 2009, 14:59
von Tyrax
Hallo nochmal,

hier der Code mit den vorgeschlagenen Verbesserungen (ist jetzt auch viel kürzer):

Code: Alles auswählen

print("""Dieses Programm berechnet die Fibonacci-Folge zu deinen Startwerten \n und gibt die Folge bis zu einem von dir gewählten Zähler an.\n""")
a1 = int(input("Geben sie das erste Element ihrer Fibonacci-Folge an: a1 ="))
a2 = int(input("Geben sie das zweite Element ihrer Fibonacci-Folge an: a2 ="))
n  = int(input("Bis zu welchem Folgenglied soll die Folge berechnet werden? n ="))
liste = [a1 , a2] #
def Fibonaccischritt():
      liste.append(liste[-1] + liste[-2])
for i in range(2,n):
  Fibonaccischritt()
print(liste)
Noch weitere Kommentare? Sonst wende ich mich mal dem nächsten Projekt zu. Grüße, Tyrax

Verfasst: Donnerstag 5. Februar 2009, 15:01
von EyDu
Pack es gleich in eine Funktion, der "Fibonaccischritt" ist vollkommen überflüssig und du wirst die globale Liste los:

Code: Alles auswählen

def fibonacci(a, b, n):
    result = [a, b]
    for i in range(len(result), n):
        result.append(result[-1]+result[-2])
    return result[:n]

Verfasst: Donnerstag 5. Februar 2009, 15:47
von Tyrax
EyDu,

das ist in der Tat besser. Ich nehme an, du hast len(result) benutzt um klarzustellen, warum da (in diesem Fall) 'ne Zwei steht. Mit Benutzereingabe und Ausgabe der Liste sieht's bei mir jetzt so aus:

Code: Alles auswählen

def fibonacci(a1, a2, n):
    liste = [a1, a2]
    for i in range(len(liste), n):
        liste.append(liste[-1]+liste[-2])
    print(liste)
a1 = int(input("a1 ="))
a2 = int(input("a2 ="))
n  = int(input("n ="))
fibonacci(a1, a2, n)
Ich habe die return-Zeile rausgenommen. Die brauche ich nur, wenn ich danach noch mit "liste" arbeiten will, oder?

Grüße, Tyrax

Verfasst: Donnerstag 5. Februar 2009, 15:49
von derdon
Schreib in Zeile 5 lieber das return hin und in Zeile 9 kommt das print zum Ausgeben. So ist Logik und Ausgabe besser voneinander getrennt.

Verfasst: Donnerstag 5. Februar 2009, 15:55
von cofi
`print' ist - wenn du noch nicht Python 3 benutzt - noch keine Funktion, also lass die Klammern weg. Hier macht das keinen großen Unterschied, da das damit nicht zum Tuple wird, aber man sollte sich das gar nicht erst falsch angewöhnen ;) (Selbst wenn man dann auf Python 3 wechselt, ist es falsch angewöhnt ;) )

Verfasst: Donnerstag 5. Februar 2009, 16:19
von Leonidas
cofi hat geschrieben:wenn du noch nicht Python 3 benutzt
Was aber wohl der Fall ist, denn das ``int(input(...))`` wäre ja in 2.x eher unsinnig und die generelle 3.0-konformheit lässt mich schließen, dass der Code für 3.0 gedacht ist.