Random Zahlen in einem Array Speichern

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.
Fabio2002
User
Beiträge: 16
Registriert: Donnerstag 2. Mai 2019, 15:49

Hallo Python Comunity, ich bin erst neu hier und auch ein frischer Anfänger in Python.
Wir haben Programmierung in der Schule ein wenig angetestet und ich möchte mich darin ein wenig weiterbilden :)

Ich habe Aufgaben im Internet gefunden für Anfänger, jedoch bei dieser habe ich irgendwie Probleme.

Man muss eine Zahl und eine Arraygröße einlesen, und diese dann mit Random zahlen füllen.
Mein Code schaut momentan so aus, kein Plan ob ich dafür eine Funktion gebraucht hätte oder nicht.
Jedenfalls kann ich Arraygrößen einlesen, jedoch wird mir dann auf jeder Stelle die selbe zufällige Zahl gespeichert :S

import random

def Array():
n = int(input("Arraygröße?: "));
z = random.randint(-100, 100,)
n = [z]*n
print(n)

Array();

Wie gesagt, wollte nur eine Hilfe, ist auch kein muss ich mach das nur Freiwillig.
Danke schon mal, lg
Fabio2002
User
Beiträge: 16
Registriert: Donnerstag 2. Mai 2019, 15:49

Edit: Hiermit hat es funktioniert, aber wäre das auch irgendwie ohne numpy(weiß leider nicht genau was das ist) funktioniert?

import numpy as np

n = int(input("Arraygröße?: "));
randnums= np.random.randint(-100,100,n)

randnums
print(randnums)
nezzcarth
User
Beiträge: 1633
Registriert: Samstag 16. April 2011, 12:47

Zur Zeit generierst du ja auch nur eine Zufallszahl, die du n-mal wiederholst. Stattdessen muss du aber n Zufallszahlen erzeugen und diese zum Beispiel an eine Liste anhängen. Schau dir doch Mal Schleifen an und welche Methoden Listen in Python haben. Alternativ kann man es auch -- etwas fortgeschritten -- mit einer List Comprehension lösen.

Übrigens brauchst du keine Semikolons am Zeilenende. 'Array' ist ein schlechter Name, da Funktionsnamen klein geschrieben sein sollten; zudem gibt es ein Modul in der Standardbibliothek, das genau so heißt. Was du da hast, ist auch eigentlich keine Funktion, da es keinen Rückgabewert hat. Die Kapselung kannst du dir an der Stelle sparen, finde ich.
Zuletzt geändert von nezzcarth am Donnerstag 2. Mai 2019, 16:51, insgesamt 1-mal geändert.
Benutzeravatar
__blackjack__
User
Beiträge: 13071
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Fabio2002: Array geht im Grunde nicht ohne Numpy, denn ohne Numpy hast Du keine Arrays. In Deinem ersten Beitrag hast Du eine Liste und kein Array. Und da hast Du n mal die selbe Zahl, weil Du genau *das* in Deinem Code sagst: Nimm eine Liste in der die Zahl z steht und erstelle eine Liste die aus n mal diesem Listeninhalt besteht. `z` ist an eine Zahl gebunden und da gibt es dann keine Information mehr wie diese Zahl mal zustande gekommen ist, also kann diese Multiplikation der Liste auch nicht bedeuten das n mal das gemacht werden soll was mal gemacht wurde um den Wert zu bestimmen der an den Namen `z` gebunden wird. Das wäre ein bisschen sehr viel Magie.

Wenn Du n mal eine Zufallszahl bestimmen willst, dann musst das das erstellen der Zufallszahl auch n mal wiederholen. Wiederholen kann man Code mittels Schleifen. Und dann muss man eine leere Liste erstellen, und in einer Schleife dann die Zufallszahlen ermitteln und an die Liste anhängen. Etwas kompakter lässt sich das dann mit einer „list comprehension“ schreiben.

Oder mit `more_itertools` (`take()`, `repeatfunc()`):

Code: Alles auswählen

In [43]: n = 10                                                                 

In [44]: take(n, repeatfunc(partial(randint, -100, 100)))                       
Out[44]: [-82, -45, 99, -54, -77, 30, 35, 32, 19, -33]
`partial()` aus `functools` und `randint()` aus `random`.

Und versuch am besten gar nicht erst Dir Abkürzungen in Namen anzugewöhnen. Was sind denn `randnums`? Auf welchem Rand liegen denn diese Nummern? ;-)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Fabio2002
User
Beiträge: 16
Registriert: Donnerstag 2. Mai 2019, 15:49

Danke für die schnellen Antworten, naja das mit den Abkürzungen habe ich so im Internet beim stöbern gefunden.

Code: Alles auswählen

import random

def Array():
    v = 1
    n = int(input("Arraygröße?: "));
    while v <= n:
        z = random.randint(-100, 100,) 
        b  = [z]
        print(b)
        v=v+1
    else:
        print("end")
    
Array();

Jetzt habe ich eine Schleife versuch, und wenn ich meine eingabe eingebe 4, dann gibt er mir auch 4 Zufällige zahlen aus. (aber halt untereinander)
Wird das Z hier immer überschrieben? kann ich am Ende irgendwie durch eine + operation diese alle in ein (array) oder wie du meintest Liste packen?
Zuletzt geändert von Fabio2002 am Donnerstag 2. Mai 2019, 17:17, insgesamt 1-mal geändert.
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

Bitte setz in Zukunft deinen Code in code-tags, die findest du im erweiterten Editor mit dem Knopf </>. Und hast du dir mal in der offiziellen Dokumentation angeschaut, was ein Listenobjekt so alles fuer Methoden kennt?
Fabio2002
User
Beiträge: 16
Registriert: Donnerstag 2. Mai 2019, 15:49

Werde ich nächstes mal machen, danke
Benutzeravatar
__blackjack__
User
Beiträge: 13071
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Fabio2002: Nicht nur `z` wird bei jedem Schleifendurchlauf ”überschrieben” sondern `b` wird jedes mal an eine Liste mit genau einem Element gebunden. Du willst eine leere Liste *vor* der Schleife erstellen, dann *in* der Schleife jeweils eine Zufallszahl an diese Liste *anhängen*, und die Liste dann *nach* der Schleife ausgeben (oder anderweitig verwenden). Und es sind nicht nur Abkürzungen schlecht, sondern in aller Regel auch einbuchstabige Namen die so gar nichts aussagen.

Bei diesem Problem ist eine ``for``-Schleife einer ``while``-Schleife vorzuziehen. Und ``else`` zu einer Schleife wo im Schleifenkörper kein ``break`` vorkommt, macht keinen Sinn.

Die Anmerkungen zum Namen und der Schreibweise von `Array` und zu den Semikolons gelten auch immer noch. :-)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Fabio2002
User
Beiträge: 16
Registriert: Donnerstag 2. Mai 2019, 15:49

@blackjack

Danke, habe das ganze jetzt wenigstens zum laufen gebracht.

Code: Alles auswählen

import random

def Array():
    v = 1
    n = int(input("Arraygröße?: "));
    m =[]
    while v <= n:
        z = random.randint(-100, 100,) 
        m.append(z)
        v=v+1
    print(m)
    
Array();
Nur die Namen und so muss ich noch ändern, es funktioniert auch mit der whileschleife(glaub ich zumindest).
Warum würde man hier eine for schleife vorziehen und was wären so "gute" Namen z.B?
Danke schon mal für die Hilfe hier!
(leider sollte man laut der angabe das iwie ohne "append" lösen, aber leider kein plan wie ich das mache :D
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

Eine for-Schleife ist nicht nur kürzer, also weniger Code, wo man Fehler suchen muß, sondern sie sagt auch jedem gleich, was passiert, ohne dass man sie erst Bedingung und Änderungen in der while-Schleife anschauen muß, und jeder verwirrt ist, warum denn keine for-Schleife benutzt wurde:

Code: Alles auswählen

def generate_random_numbers(size):
    numbers = []
    for _ in range(size):
        numbers.append(random.randint(-100, 100))
    return numbers

def main():
    size = int(input("Arraygröße?: "));
    print(generate_random_numbers(size))
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

@Fabio und nur damit du es schon mal gehört hast, es gibt "List Comprehensions", damit wird deine while-Schleife zum Einzeiler.

Code: Alles auswählen

def generate_random_numbers(size):
    return [random.randint(-100, 100) for _ in range(size)]
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Fabio2002
User
Beiträge: 16
Registriert: Donnerstag 2. Mai 2019, 15:49

Hallo zusammen, ich habe eine weitere Frage, diese hatte aber nichts mit dem letzten Problem zu tun, Ich wusste nur nicht ob ich einen neuen Thread erstellen soll oder hier weitermachen.
Jedenfalls habe ich follgenden code, ich wollte eine lineare Suche machen, also genau eine Zahl in meiner Liste finden.
Das sollte eigentlich soweit schon stimmen(hoff ich) ich habe zwei if Bedingungen gemacht sodass wenn er die Zahl findet, mir sagt wo. Und wenn er sie beim jetzigen Durchlauf nicht gefunden hat wieder beginnt(continue).
Jedoch wie kann ich anzeigen lassen dass die gewollte Zahl, bei den erstellten Zufallszahlen nicht vorhanden ist? Hier mal der code:

Code: Alles auswählen

import random   

#def elimDoppel():
#    a = numbers
#    a = list(set(numbers)) #löscht alle doppelt enthaltenen Zahlen
#    print(a)        

def generate_random_numbers(size): 
    for i in range(size):
        numbers.append(random.randint(-100, 100))
    print(numbers)
    return numbers

def linear_search(numbers, n):
    for i in range(0, len(numbers)):
            if numbers[i] == n:
                print(str(n) + " found at index " + str(i))
            if numbers[i] != n:
               continue
            
    
    
    return linear_search
                
                
numbers = []
generate_random_numbers(100);  
print();
#elimDoppel();
linear_search(numbers, 16);      

Ich habe schon versucht nur einen String hinter die != Bedigung zu packen, aber war ja klar dass er es mir dann so oft schreibt wie ich Zahlen angegeben habe.
Also wie kann ich sagen ("und wenn in der Liste nicht vorhanden, dann...")
Stehe ich hier nur etwas auf dem Schlauch oder ist das kompletter Käse?

Danke schon mal
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das continue ist ueberfluessig, denn die Schleife laeuft doch von alleine weiter. Und der in Python uebliche Weg, zu kommunizieren, dass etwas nicht geklappt hat, waere eine Exception. Womit auch deine Funktion linear_search anders aussehen sollte: die ist jetzt nicht so besonders gut, weil sie nicht nur die Suche durchfuehrt, sondern GLEICHZEITIG die Ausgabe erledigt. Aber willst du jedes mal eine Ausgabe, wenn du etwas suchst? In einem echten Programm garantiert nicht!

Also muss linear_search anders vorgehen:
- wenn die Zahl gefunden wurde, liefere sie mit return zurueck
- wenn nicht, schmeisse eine Exception.

Und im Code drumrum entscheidest du dann, was du machst: print, und wenn die Exception fliegt, abfangen und "wurde nicht gefunden" ausgeben.
Benutzeravatar
__blackjack__
User
Beiträge: 13071
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Fabio2002: Nach einem ``if`` beim nächsten ``if`` auf genau das Gegenteil als beim ersten zu testen ist unsinnig – dafür gibt es ``else`` zum ``if``. Das ``continue`` macht aber auch überhaupt keinen Sinn, denn das macht mit dem nächsten Schleifendurchlauf weiter – also genau das was *sowieso* an der Stelle passieren würde. Man sollte sich den Einsatz von ``continue`` auch immer überlegen, denn das ist eine unbedingte Sprunganweisung aus einem Block heraus, die man nicht an der Einrückung erkennen kann. Zudem kann das vorhanden sein von ``continue`` das weiterentwickeln von Code schwer machen, weil man dann nicht mehr so einfach den Körper oder Teile davon in eine eigene Funktion heraus ziehen kann.

Mir ist nicht so ganz klar was Du genau willst. Wenn es Dir reicht das erste Auftreten der gesuchten Zahl auszugeben, dann kannst Du die Schleife nach dem finden einfach mit ``break`` verlassen und die Ausgabe das nichts gefunden wurde in ein ``else`` zum ``for``-Schreiben.

Sonstiges: Die `generate_random_numbers()`-Funktion ist falsch, weil die einfach das globale `numbers` befüllt, was es nicht geben dürfte, statt selbst eine Liste zu erstellen. Du gibst `numbers` ja auch an den Aufrufer zurück – so macht man das, aber eben kein globales sondern ein lokales `numbers`.

Das `linear_search()` sich am Ende selbst an den Aufrufer zurück gibt, macht keinen Sinn. Wenn eine Funktion kein Ergebnis hat, braucht man auch kein ``return`` mit einem Ausdruck, und am Ende einer Funktion braucht man auch kein ``return`` ohne einen Ausdruck, denn da ist die Funktion ja sowieso am Ende angekommen.

Was sollen die Semikolons in dem Quelltext? Python ist kein C, Java, …

Das mit dem ``+`` und `str()` um Zeichenketten und Werte zusammenzustückeln ist auch kein Python sondern eher BASIC. In Python gibt es dafür Zeichenkettenformatierung mit der `format()`-Methode auf Zeichenketten. Oder in diesem Fall könnte man die drei Teile auch einfach als einzelne Argumente an `print()` übergeben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@Fabio2002: benutze keine globalen Variablen. `generate_random_numbers` sollte eine neue Liste zurückgeben und nicht irgendeine globale Liste verwenden, wie es hier schon mehrfach gezeigt wurde.
Wenn eine if-Bedingung exakt das Gegenteil des vorherigen if-Blocks ist, benutz man else:

Code: Alles auswählen

            if numbers[i] == n:
                print(str(n) + " found at index " + str(i))
            else:
               continue
Wobei hier das `continue` überflüssig ist, weil außer dem ersten if-Block nichts in der for-Schleife gemacht wird, und auch sonst `continue` vermieden werden sollte, weil es den Programmablauf undurchsichtig macht.

String setzt man nicht mit + zusammen, sondern benutzt Stringformatierung.
Dass `linear_search` sich selbst als Rückgabewert zurückgibt ist quatsch. Normalerweise würde man erwarten, dass der gefundene Index zurückgegeben wird.
Bleibt also:

Code: Alles auswählen

def linear_search(numbers, n):
    for i in range(0, len(numbers)):
            if numbers[i] == n:
                print(f"{n} found at index {i}")
Über einen Index zu iterieren, ist schlecht, wenn man auch direkt über die Elemente iterieren kann (mit enumerate, falls man den Index braucht), richtig wäre also:

Code: Alles auswählen

def linear_search(numbers, n):
    for i, num in enumerate(numbers):
            if num == n:
                print(f"{n} found at index {i}")
Wenn Du wissen willst, ob es überhaupt vorkommt, kannst Du Dir das z.B. mit einem Flag merken.

Jetzt hast Du aber soetwas ähnliches wie `list.index` nachprogrammiert.
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Die for-Schleife kann auch ein else: haben.

Code: Alles auswählen

def linear_search(numbers, n):
    for index, number in enumerate(numbers):
            if number == n:
                print(f"{number} found at index {index}")
                break
    else:
           print(f"{n} is not in list")
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
__blackjack__
User
Beiträge: 13071
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ThomasL: Was aber so keinen Sinn macht, denn das wird bei Dir *immer* ausgeführt. Da fehlt ein ``break``.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Habe ich 2 sek nach dem posten auch gesehen, jetzt fehlt es nicht mehr und nun macht es Sinn Simsalabim. :-)
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@ThomasL: jetzt suchst Du nur noch nach dem ersten Vorkommen, und das ist die index-Funktion:

Code: Alles auswählen

def linear_search(numbers, n):
    try:
        index = numbers.index(n)
        print(f"{n} found at index {index}")
    except ValueError:
           print(f"{n} is not in list")
Fabio2002
User
Beiträge: 16
Registriert: Donnerstag 2. Mai 2019, 15:49

mhm oke, ich weiß ich bin ziemlich schlecht :roll: aber naja^^

Code: Alles auswählen

def generate_random_numbers(size): 
    numbers = []
    for i in range(size):
        numbers.append(random.randint(-100, 100))
    return numbers
Hiermit generier ich ja meine Liste, und diesmal nicht global? Hab ich das richtig verstanden.

Code: Alles auswählen

def linear_search(numbers, n):
    for i in range(0, len(numbers)):
            if numbers[i] == n:
                print(f"{n} found at index {i}")
    else:
        print("die Zahl ist nicht in der Liste vorhanden")
Aber wie kann ich dann sagen dass er aus der oberen Liste eine Gewisse Zahl sucht.
Weil ich kann ja unten als parameter dann nicht numbers verwenden?

Und bitte für die die es nervt dass ich ein totaler Anfänger bin, ihr braucht nicht zu Antworten, ich nehme kritik und Fehler dankend an, aber oft wirkt es ein wenig von oben herab :)
Antworten