Hilfe erbeten, Funktion und Liste

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
haeuslermartin
User
Beiträge: 66
Registriert: Sonntag 21. April 2013, 10:12

Code: Alles auswählen

import random

per=[]
wieoft=[]
x=5 
def perioden():
    for i in range(x):
        per.append(random.randint(1,12))
    wieoft.append(per.count(1))
    wieoft.append(per.count(2))
    wieoft.append(per.count(3))
    wieoft.append(per.count(4))
    wieoft.append(per.count(5))
    wieoft.append(per.count(6))
    wieoft.append(per.count(7))
    wieoft.append(per.count(8))
    wieoft.append(per.count(9))
    wieoft.append(per.count(10))
    wieoft.append(per.count(11))
    wieoft.append(per.count(12))
    print(per)
    print(wieoft)

perioden()
>>>
[2, 11, 10, 3, 10]
[0, 1, 1, 0, 0, 0, 0, 0, 0, 2, 1, 0]
>>>
# bis hierher einwandfrei, aber bei mehrmaliger Ausführung der Funktion:

Code: Alles auswählen

for i in range(2):
    perioden()
>>>
[11, 1, 3, 5, 2]
[1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0]
[11, 1, 3, 5, 2, 3, 12, 9, 12, 1]
[1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 1, 2, 0, 1, 0, 0, 0, 1, 0, 1, 2]
>>>
die Ergebnisse werden in einen Topf geworfen, warum nur, ich quäle mich seit Tagen damit herum, normal wären doch zwei getrennte
Ergebnisse, etwa so:

>>>
[11, 1, 3, 5, 2]
[1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0]
[3, 12, 9, 12, 1]
[2, 1, 2, 0, 1, 0, 0, 0, 1, 0, 1, 2]
>>>

oder :K :

>>>
[[11, 1, 3, 5, 2],[3, 12, 9, 12, 1]]
[[1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0], [2, 1, 2, 0, 1, 0, 0, 0, 1, 0, 1, 2]]
>>>
Zuletzt geändert von Anonymous am Sonntag 8. Januar 2017, 23:44, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@haeuslermartin: Warum erwartest Du da etwas anderes? Du erstellst die leeren Listen `per` und `wieoft` und jedes mal wenn `perioden()` aufgerufen wird, werden mehr Werte an diese beiden Listen angehängt. An welcher Stelle erwartest Du die Magie das deren Inhalt bei einem weiteren Aufruf gelöscht wird ohne das das tatsächlich irgendwo explizit im Code stehen würde?

Was ”falsch” ist, ist das `perioden()` keine ”echte” Funktion ist. Da werden keine Werte übergeben, sondern die ”Funktion” greift einfach so auf Werte von ausserhalb zu und verändert sogar Listen ausserhalb der Funktion. So etwas wird ziemlich schnell sehr unübersichtlich und fehleranfällig. Alle Werte (ausser Konstanten) die eine Funktion verwendet sollte die Funktion als Argumente betreten. Ergebnisse sollten sie als Rückgabewerte verlassen. Und ”echte” Funktionen sollten Datenstrukturen nicht verändern, sondern eher neue, veränderte erstellen.

Edit: Für das zählen würde man auch eine Schleife verwenden, statt 12 mal fast die gleiche Codezeile zu schreiben. Oder gleich `collections.Counter` oder in der ersten Schleife schon mitzählen.
haeuslermartin
User
Beiträge: 66
Registriert: Sonntag 21. April 2013, 10:12

vielen Dank für die Antwort, aber so ganz schnall ichs immer noch nicht, wird denn perioden() mit -for i in range- nicht genauso immer wieder neu
gestartet, wie ich es auch "von Hand" machen würde? da kommen die Ergebnisse nämlich getrennt ...
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@haeuslermartin: versuch mal genau nachzuvollziehen, wann Du was mit Deinen Listen per und wieoft machst.
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Probier's mal hiermit, das könnte beim Verständnis helfen, was in deinem Code passiert: PythonTutor.com/Visualize.html
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
BlackJack

@haeuslermartin: Wie machst Du das bitte von Hand? Wenn Du da wirklich nur `perioden()` mehr als einmal aufrufst, dann wirst Du dort genau das gleiche Verhalten sehen wie im Programm:

Code: Alles auswählen

In [1]: import random

In [2]: per=[]

In [3]: wieoft=[]

In [4]: x=5

In [5]: def perioden():
   ...:     for i in range(x):
   ...:         per.append(random.randint(1,12))
   ...:     wieoft.append(per.count(1))
   ...:     wieoft.append(per.count(2))
   ...:     wieoft.append(per.count(3))
   ...:     wieoft.append(per.count(4))
   ...:     wieoft.append(per.count(5))
   ...:     wieoft.append(per.count(6))
   ...:     wieoft.append(per.count(7))
   ...:     wieoft.append(per.count(8))
   ...:     wieoft.append(per.count(9))
   ...:     wieoft.append(per.count(10))
   ...:     wieoft.append(per.count(11))
   ...:     wieoft.append(per.count(12))
   ...:     print(per)
   ...:     print(wieoft)
   ...: 

In [6]: perioden()
[6, 4, 4, 2, 9]
[0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0]

In [7]: perioden()
[6, 4, 4, 2, 9, 12, 3, 3, 8, 12]
[0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 2, 2, 0, 1, 0, 1, 1, 0, 0, 2]
Natürlich wird ``for i in …`` da zweimal ausgeführt, aber warum sollte das auf magische Weise vorhandene Elemente aus den Listen *entfernen* wenn Dein Code doch nur mit `append()` immer mehr Elemente anhängt.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Steve Oualline, "Practical C Programming":
If we don't write code like this, then we don't have to worry about such questions.
In specifications, Murphy's Law supersedes Ohm's.
haeuslermartin
User
Beiträge: 66
Registriert: Sonntag 21. April 2013, 10:12

ich stand voll auf dem Schlauch, sorry, -klar, wenn ich das Programm neu starte, starte ich auch die Listen immer wieder neu, darum die Einzelergebnisse, ist wahrscheinlich das Alter ... nochmals danke

jetzt so: wenns jemand interessiert, die Ergebnisse könnte man natürlich mittels Binominalfunktion auch math. erhalten, aber ich bin weder Mathematiker, noch Informatiker, sondern nur Rentner, so probier ich halt ein kleines Programm zu schreiben, das mir empirische Ergebnisse ermöglicht:

Code: Alles auswählen

import random

alle=[]
x=10 
def perioden():
    per=[]
    wieoft=[]
    for i in range(x):
        per.append(random.randint(1,12))
    wieoft.append(per.count(1))
    wieoft.append(per.count(2))
    wieoft.append(per.count(3))
    wieoft.append(per.count(4))
    wieoft.append(per.count(5))
    wieoft.append(per.count(6))
    wieoft.append(per.count(7))
    wieoft.append(per.count(8))
    wieoft.append(per.count(9))
    wieoft.append(per.count(10))
    wieoft.append(per.count(11))
    wieoft.append(per.count(12))
    #print(per)
    #print(wieoft)
    alle.append(wieoft.count(2)+wieoft.count(3)+wieoft.count(4))
for i in range(1000):
    perioden()
#print()
#print(alle)
print("von",len(alle), "Perioden a`", x, "coups haben",alle.count(1)+alle.count(2)+alle.count(3),"Perioden Mehrfachtransversalen")
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
von 100 Perioden a` 4 coups haben 43 Perioden Mehrfachtransversalen
>>> ================================ RESTART ================================
>>>
von 1000 Perioden a` 4 coups haben 459 Perioden Mehrfachtransversalen
>>> ================================ RESTART ================================
>>>
von 100 Perioden a` 5 coups haben 62 Perioden Mehrfachtransversalen
>>> ================================ RESTART ================================
>>>
von 1000 Perioden a` 5 coups haben 634 Perioden Mehrfachtransversalen
>>> ================================ RESTART ================================
>>>
von 100 Perioden a` 6 coups haben 76 Perioden Mehrfachtransversalen
>>> ================================ RESTART ================================
>>>
von 1000 Perioden a` 6 coups haben 769 Perioden Mehrfachtransversalen
>>> ================================ RESTART ================================
>>>
von 100 Perioden a` 7 coups haben 89 Perioden Mehrfachtransversalen
>>> ================================ RESTART ================================
>>>
von 1000 Perioden a` 7 coups haben 884 Perioden Mehrfachtransversalen
>>> ================================ RESTART ================================
>>>
von 100 Perioden a` 8 coups haben 98 Perioden Mehrfachtransversalen
>>> ================================ RESTART ================================
>>>
von 1000 Perioden a` 8 coups haben 943 Perioden Mehrfachtransversalen
>>> ================================ RESTART ================================
>>>
von 100 Perioden a` 9 coups haben 98 Perioden Mehrfachtransversalen
>>> ================================ RESTART ================================
>>>
von 1000 Perioden a` 9 coups haben 959 Perioden Mehrfachtransversalen
>>> ================================ RESTART ================================
>>>
von 100 Perioden a` 10 coups haben 93 Perioden Mehrfachtransversalen
>>> ================================ RESTART ================================
>>>
von 1000 Perioden a` 10 coups haben 915 Perioden Mehrfachtransversalen
>>>

interessant dabei, dass sich Zufallsergebnisse nicht linear entwickeln ... und hundert Versuche ausreichen
Zuletzt geändert von Anonymous am Dienstag 10. Januar 2017, 10:43, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@haeuslermartin: solche Fehler passieren einfach nicht so leicht, wenn man wirklich Funktionen schreiben würde und nicht einfach von irgendwoher Werte zusammensammeln würde:

Code: Alles auswählen

import random
 
def perioden(x):
    per = [random.randint(1,12) for _ in range(x)]
    wieoft = [per.count(i) for i in range(1,13)]
    return sum(wieoft.count(i) for i in range(2,5))

def main():
    x = 10
    alle = [perioden(x) for i in range(1000)]
    count = sum(alle.count(i) for i in range(1,4))
    print("von {} Perioden a `{}` coups haben {} Perioden Mehrfachtransversalen".format(len(alle), x, count))

if __name__ == '__main__':
    main()
Antworten