Seite 1 von 1

return aus Funktion übergibt nicht gewünschten Wert ?

Verfasst: Sonntag 13. Mai 2007, 01:44
von kaytec
Das verstehe ich nicht ? Es wird die erste gebildete Liste übergeben. Warum nicht die letzte erzeugte ?

Code: Alles auswählen

import random
a = list()

def erzeuge(a):
    while True:
        for x in range (9):  
            a.append(random.randint(1,9))
        if len(set(a)) < 9:
            a = list()
            continue
        print a
        return a 
        break
  
    
erzeuge(a)
print a
gruss und dank frank

Verfasst: Sonntag 13. Mai 2007, 02:52
von Actimehl
Macht dieser Code das, was du willst?
Das Problem liegt darin wie Namen an Objekte gebunden werden.

Code: Alles auswählen

import random
b = list()

def erzeuge(a):
    while True:
        for x in range (9): 
            a.append(random.randint(1,9))
        if len(set(a)) < 9:
            a = list()
            continue
        print a
        return a
        break
 
   
print erzeuge(b)
print b

Verfasst: Sonntag 13. Mai 2007, 08:22
von kaytec
Mein code macht was es will - nein, er macht schon was ich möchte. Er erzeugt eine Liste mit Zufallszahlen. Damit diese Liste keine doppelten Einträge erhält mache ich das mit dem set(). Doch übergebe ich diese Liste, kommt nicht die Liste mit den unterschiedlichen Zufallszahlen raus, sondern die erste Liste, die beim Start erzeugt wird.

Code: Alles auswählen

import random
a = list()

def erzeuge(a):
    while True:
        for x in range (9):  
            a.append(random.randint(1,9))
        print a
        if len(set(a)) < 9:
            a = list()
            continue
        print a
        return a 
        break
  
    
erzeuge(a)
print a
so kann man es auch machen und vergleichen.

Code: Alles auswählen

import random
a = list()

def erzeuge(a):
    while True:
        for x in range (9):  
            a.append(random.randint(1,9))
        if len(set(a)) < 9:
            a = list()
            continue
        print a
        ausgabe(a)
        break
  
def ausgabe(a):
    print a
    
erzeuge(a)
so geht es jetzt ?

gruss und dank frank

Verfasst: Sonntag 13. Mai 2007, 09:56
von Leonidas
kaytec hat geschrieben:Mein code macht was es will - nein, er macht schon was ich möchte. Er erzeugt eine Liste mit Zufallszahlen. Damit diese Liste keine doppelten Einträge erhält mache ich das mit dem set(). Doch übergebe ich diese Liste, kommt nicht die Liste mit den unterschiedlichen Zufallszahlen raus, sondern die erste Liste, die beim Start erzeugt wird.
Also zumindest im ersten Quelltext konnte ich dein Problem nicht nachvollziehen. Das einzige was ich gesehen habe ist, dass er ziemlich unperformant ist. Stell dir vor, die Länge des sets beträgt die ersten 2000 male acht statt neun. Dann wird die ``while``-Schleife 2001 Mal durchlaufen, bis eine passende Sequenz gefunden wurde.

Davon abgesehen, gibt es für sowas ``random.shuffle()``:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import random

random_numbers = range(1, 10)
random.shuffle(random_numbers)
print random_numbers
Finde ich jetzt ein wenig lesbarer. Die Zahlen kommen nie doppelt vor, dafür ist automatisch gesorgt.

Verfasst: Sonntag 13. Mai 2007, 10:18
von kaytec
Danke Leonidas !

Mein code ist Trail and Error - ok, hast schon recht. Warum verhält sich die Liste a bei der Übergabe so?

gruss und dank frank

Verfasst: Sonntag 13. Mai 2007, 10:34
von BlackJack
In Deinem ersten Quelltext wird ausserhalb der Funktion eine Liste erzeugt und an den Namen `a` im Namensraum des Moduls gebunden. In der Funktion wird diese Liste an den lokalen Namen `a` gebunden und mit Werten gefüllt. Beide Namen verweisen auf das selbe `list`-Objekt. Wenn die Liste nicht den Bedingungen entspricht, wird in der Schleife eine *neue* Liste erzeugt und an den lokalen Namen `a` gebunden. Der Name im Modul verweist immer noch auf das zuerst gefüllte `list`-Objekt!

Am Ende des Quelltextes wird die Funktion aufgerufen und mit dem Rückgabewert wird nichts gemacht! Und danach wird die Liste ausgegeben, die an `a` gebunden ist. Also die erste "Befüllung".

Verfasst: Sonntag 13. Mai 2007, 10:44
von kaytec
Jetzt habe ich es glaub ich verstanden - ich hätte schreiben müssen:

Code: Alles auswählen

ausgabe = erzeuge()
print ausgabe
gruss frank

Verfasst: Sonntag 13. Mai 2007, 11:20
von kaytec
Habe mal den gleichen Fehler in die neue Funktion eingebaut. Ich erzeuge die Liste a und verändere sie lokal in der Funktion. Global ist sie aber noch als 'leere' Liste vorhanden. Diese Liste wird dann auch so ausgegeben ?

Code: Alles auswählen

import random
a = list()
def erzeuge(a):
    random_nummer = range(1, 10)
    random.shuffle(random_nummer)
    a = random_nummer
    return a

b = erzeuge(a)
print a
print b
gruss und dank frank

Verfasst: Sonntag 13. Mai 2007, 11:42
von Leonidas
kaytec hat geschrieben:Habe mal den gleichen Fehler in die neue Funktion eingebaut. Ich erzeuge die Liste a und verändere sie lokal in der Funktion. Global ist sie aber noch als 'leere' Liste vorhanden. Diese Liste wird dann auch so ausgegeben ?
Natürlich wird die die modulglobale Liste unter dem Namen ``a`` nicht verändert. Wenn du zu ``a`` etwas in einem Funktionsscope (Namensraum) zuweist, wird die globale Variable "überdeckt" und nicht überschrieben. Dies ist das Standardverhalten von Python und es ist auch gut so. Es gibt aber die Möglichkeit Globale Variablen zu überschrieben: sollte man aber wirklich, wirklich nur in Ausnahmefällen tun! Das macht das Programm wesentlich weniger verständlich.

So sieht es mit überschreiben globaler Variablen aus:

Code: Alles auswählen

import random
a = list()
def erzeuge():
    global a
    random_number = range(1, 10)
    random.shuffle(random_number)
    a = random_number
    return a

b = erzeuge()
print a
print b
Übrigens, so etwas geht auch:

Code: Alles auswählen

import random
a = list()
def erzeuge(a):
    random_number = range(1, 10)
    random.shuffle(random_number)
    a.extend(random_number)

erzeuge(a)
print a
Da ``a`` eine Liste ist und Listen mutabel (also veränderlich) sind, kann man an sie etwas anhängen, ohne ``global`` Schlüsselwort. Das liegt daran, dass im ersten Code die Liste ``a`` mit einer neuen Liste überschrieben wird und im zweiten Beispiel wird an die Liste a nur etwas drangehängt - ohne eine neue Liste zu erstellen.

Verfasst: Sonntag 13. Mai 2007, 11:53
von BlackJack
@kaytec: Du veränderst die übergebene Liste nicht in der Funktion, Du erzeugst eine völlig neue Liste und gibst der den lokalen Namen `a`. Selbst bei einem ``global a`` am Anfang Deiner Funktion würde die ursprüngliche Liste nicht verändert, sondern ersetzt. Wäre sie noch auf anderem Wege erreichbar, weil sie zum Beispiel noch an einen anderen Namen gebunden wäre, dann würde dort immer noch eine leere Liste ansprechbar sein.