Die ersten 15 Primzahlen ausgeben

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.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

@problembär, naja bei deinem Beispiel gibt es einige bessere Methoden:

Code: Alles auswählen

x = 0
while x <= 10:
    print "x = %d." % x
    x += 1
print "Schleife beendet."
oder gleich eine for-Schleife:

Code: Alles auswählen

for x in xrange(11):
    print "x = %d." % x
print "Schleife beendet."
Des Weiteren verknüpft man Strings (normalerweise) nicht mit "+".
the more they change the more they stay the same
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@problembär: Dir ist schon klar, dass der OP diese Schleife jetzt schon kapiert hatte? Du zeigst ihm nichts neues - außer, dass Du drei Zeilen Code schreibst, wo man mit `for index in count():` mit einer auskommt :roll: Natürlich würde man als Anfänger da nicht drauf kommen, weil man diese Funktion schlicht nicht kennt! Aber wenn man sie nun einmal gesehen hat und einem klar ist, was sie macht, kann man sie sicherlich benutzen. Der OP steckt jetzt dabei fest, dass ihm nicht klar ist, wie man einzelne Teile modularisiert und alles zu einem Guss zusammenfügt.

@Artur:
Hattet Ihr noch keine Funktionen? Wenn nein, kannst Du das auch ohne lösen. Du packst eben den Test auf eine Primzahl einfach in den Schleifenrumpf (also da wo das `print(index)` steht).
Falls ja, packst Du das einfach in eine Funktion, die Dir einen Booleschen Wert zurückliefert:

Code: Alles auswählen

for index in count():
    # hier Deinen Code 
    # und Abbruchbedingung prüfen
Oder aber mit einer Funktion:

Code: Alles auswählen

def is_prime(value):
    # hier den Code zum Prüfen; Du musst aber
    # True und False entsprechend zurückgeben

for index in count():
    # hier wird die Funktion aufgerufen und der Rückgabewert
    # ausgewertet (`is_prime` gibt ja `True` oder `False` zurück!)
    if is_prime(index):
        print("{} ist eine Primzahl".format(str(index)))
    # Abbruch prüfen
Vorteil der Funktionsmethode: Du kannst die Funktion vollkommen separat vom ganzen Rest entwickeln und in einer interaktiven Shell testen! Sofern sie funktioniert, baust Du sie dann eben in den Rahmen ein.

Da Du Dir die Primzahlen ja eigentlich "merken" sollst, müsstest Du Dich jetzt noch mit Listen vertraut machen:

Code: Alles auswählen

In [72]: primes = [2, 3, 5]

In [73]: primes.append(7)

In [74]: primes
Out[74]: [2, 3, 5, 7]

In [75]: len(primes)
Out[75]: 4
Diese Basics musst Du nun noch in den Code integrieren. Du musst also ganz außen erst einmal eine leere Liste anlegen. Dann fügst Du mittels `append` immer dann eine Primzahl hinzu, wenn der Test positiv war (egal ob durch eine Funktion getestet oder "inline"). Direkt im Anschluss kannst Du die Abbruchbedingung nun auf die Länge (=Anzahl an Elementen der Liste) umschreiben (vgl. [75]).

Hinweis: Dies musst Du nur prüfen, wenn Du eine neue Primzahl an die Liste gehängt hast und nicht in jedem Durchgang!

Letztlich kommen wir auf dieses Gerüst:

Code: Alles auswählen

def is_prime(value):
    # hier den Code zum Prüfen; Du musst aber
    # True und False entsprechend zurückgeben

primes = []
for index in count():
    if is_prime(index):
        # Primzahl an Liste anhängen
        # Abbruch prüfen
So schwer ist das doch gar nicht!

@Dav1d: `range` klappt hier ja gerade nicht; das kannst Du schon an der Aufgabenstellung ablesen ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Artur
User
Beiträge: 47
Registriert: Freitag 21. Oktober 2011, 10:55

Code: Alles auswählen

L=[]
for n in range(2, 60):
    for x in range(2, n):
        if n % x == 0:
            break
    else:
        print n, 'ist eine Primzahl'
        L.append(n)
        print L

Out:
2 ist eine Primzahl
[2]
3 ist eine Primzahl
[2, 3]
5 ist eine Primzahl
[2, 3, 5]
7 ist eine Primzahl
[2, 3, 5, 7]
11 ist eine Primzahl
[2, 3, 5, 7, 11]
13 ist eine Primzahl
[2, 3, 5, 7, 11, 13]
17 ist eine Primzahl
[2, 3, 5, 7, 11, 13, 17]
19 ist eine Primzahl
[2, 3, 5, 7, 11, 13, 17, 19]
23 ist eine Primzahl
[2, 3, 5, 7, 11, 13, 17, 19, 23]
29 ist eine Primzahl
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
31 ist eine Primzahl
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]
37 ist eine Primzahl
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]
41 ist eine Primzahl
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41]
43 ist eine Primzahl
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43]
47 ist eine Primzahl
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
53 ist eine Primzahl
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53]
59 ist eine Primzahl
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59]
Hey! Wie man sieht werden jetzt zeitgleich einer Liste Elemente hinzuaddiert. Ich habe jetzt versucht irgendwo ein if len(L) <=15: break einzubauen, was aber leider nicht geklappt hat. Die Anzahl der Primzahlen ist immer noch von der range abhängig (60). Das sind jetzt genau 17 Primzahlen. die 47 ist die 15. Primzahl. Dh wenn ich es hinbekomme bei einer Listenlänge von 15 ein break einzubauen, müsste die Ausgabe bei der 47 stehenbleiben. Wie mache ich das jetzt.. *grübel*
problembär

Artur hat geschrieben:Die Anzahl der Primzahlen ist immer noch von der range abhängig (60). Das sind jetzt genau 17 Primzahlen. die 47 ist die 15. Primzahl. Dh wenn ich es hinbekomme bei einer Listenlänge von 15 ein break einzubauen, müsste die Ausgabe bei der 47 stehenbleiben. Wie mache ich das jetzt.. *grübel*
Oh Mann, deshalb ja die 'while'-Konstruktion (und keine for-Schleife). In meinem Beispiel

Code: Alles auswählen

x = 0
while True:
    print "x = " + str(x) + "."
    x += 1
    if x == 10:
        break
print "Schleife beendet."
erhöhst Du x immer nur dann, wenn Du eine Primzahl gefunden hast. Und dann brichst Du die Schleife ab, wenn x == 15 ist.
Jetzt klar?
Artur
User
Beiträge: 47
Registriert: Freitag 21. Oktober 2011, 10:55

Sry :-O habs auch so hinbekommen und kann jetzt nicht mehr umdenken.

Code: Alles auswählen

L=[]
for n in range(2, 60):
    for x in range(2, n):
        if n % x == 0:
            break
        elif len(L)==15:
            break
    else:
        print n, 'ist eine Primzahl'
        L.append(n)

Out:
2 ist eine Primzahl
3 ist eine Primzahl
5 ist eine Primzahl
7 ist eine Primzahl
11 ist eine Primzahl
13 ist eine Primzahl
17 ist eine Primzahl
19 ist eine Primzahl
23 ist eine Primzahl
29 ist eine Primzahl
31 ist eine Primzahl
37 ist eine Primzahl
41 ist eine Primzahl
43 ist eine Primzahl
47 ist eine Primzahl
JAU! Das ist jetzt ne echte Erlösung. Auch wenn das nicht die schönste Lösung ist, es ist eine Lösung ^.^. Thx Hypie! Dass du den hohlen rookie nicht hängen lassen hast <3. Dein letzter Tipp hat meinem geschädigten Hirn auf die Sprünge geholfen. Nun kann ich beruhigt schlafen gehen!
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

So mal etwas überarbeitet:

Code: Alles auswählen

MAX_PRIMES = 15

L=[]
for n in itertools.count():
    for x in xrange(2, n):
        if n % x == 0:
            break
    else:
        print n, 'ist eine Primzahl'
        L.append(n)
        if len(L) == MAX_PRIMES:
            break
//Edit: Absenden mit Vorschau verwechselt …
the more they change the more they stay the same
BlackJack

@Artur: Ein recht eigenwilliger Programmfluss. Und immer noch davon abhängig, dass Du vor dem berechnen wissen musst wie das Ergebnis, also die 15. Primzahl, aussieht. Was in meinen Augen damit keine richtige Lösung ist. Wenn das eine Lösung ist, dann wäre das hier auch eine:

Code: Alles auswählen

for p in [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]:
    print p, 'ist eine Primzahl'
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

problembär hat geschrieben: Oh Mann, deshalb ja die 'while'-Konstruktion (und keine for-Schleife). In meinem Beispiel
Oder eben die bessere Lösung mit `itertools.count`. Wobei ich zugeben muss, dass Artur nichts von meinen ganzen Schnipseln verstanden hat. Schade, ich glaube kaum, dass man es jemanden noch deutlicher vorkauen kann - aber vermutlich ist er nicht mehr konzentriert und komplett überlastet. Kenne ich auch noch aus Studententagen.

So, daher nun hier mal meine Lösung:

Code: Alles auswählen

from itertools import count
from math import sqrt

def is_prime(value, primes):
    return all(value % prime for prime in primes if int(sqrt(prime)) < value)

def calc_prime_values(limit):
    # initial knowledge
    primes = [2]
    for i in count(3, 2):
        if is_prime(i, primes):
            primes.append(i)
            if len(primes) == limit:
                break
    return primes
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
pillmuncher
User
Beiträge: 1530
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

problembär hat geschrieben:
Artur hat geschrieben:Die Anzahl der Primzahlen ist immer noch von der range abhängig (60). Das sind jetzt genau 17 Primzahlen. die 47 ist die 15. Primzahl. Dh wenn ich es hinbekomme bei einer Listenlänge von 15 ein break einzubauen, müsste die Ausgabe bei der 47 stehenbleiben. Wie mache ich das jetzt.. *grübel*
Oh Mann, deshalb ja die 'while'-Konstruktion (und keine for-Schleife).
Ich behaupte immer noch, dass das Problem rein gar nichts damit zu tun hat, ob man eine while- oder eine for-Schleife benutzt:

Code: Alles auswählen

n = 0
for x in itertools.count(2):
    if is_prime(x):
        print str(x) + ' ist eine Primzahl'
        n += 1
        if n = 15:
            break

# --8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<--

n = 0
x = 2
while True:
    if is_prime(x):
        print str(x) + ' ist eine Primzahl'
        n += 1
        if n = 15:
            break
    x += 1
Die while-Version ist IMO immer noch komplizierter. Insbesondere deswegen, weil sie nur eine verkappte for-Schleife ist.

Ich vermute, und korrigiere mich bitte, falls es sich anders verhält, dass du als Ballast das Verständnis von for-Schleifen aus den traditionellen prozeduralen Sprachen mitschleppst. Also "erzeuge aus diesen Anfangsbedingungen mittels jenes Gesetzes eine Folge von Zahlen und verarbeite dann jede" statt pythonisch zu denken "verarbeite jedes Element der Folge, die durch jene Funktion bereitgestellt wird". Der Unterschied ist letztlich der zwischen prozeduralem und deklarativem Denken.
In specifications, Murphy's Law supersedes Ohm's.
BlackJack

Lösungsansatz ohne ``while`` und ohne ``break``:

Code: Alles auswählen

from itertools import count, islice


def iter_primes():
    primes = [2]
    yield 2
    for n in count(3, 2):
        if all(n % p != 0 for p in primes):
            yield n
            primes.append(n)


def main():
    for prime in islice(iter_primes(), 15):
        print prime, 'ist eine Primzahl.'


if __name__ == '__main__':
    main()'
problembär

@Artur: Leider denke ich mit BlackJack auch, daß Dein Programm keine Lösung der Aufgabe darstellt, weil es nicht selbständig die Primzahlen ermittelt. Wenn Du das daher so abgibst, bin ich überzeugt davon, daß Du damit eine schlechte Note erhalten würdest. Bitte versuche noch etwas länger, über das Problem nachzudenken.

@pillmuncher: Damit, daß ich nicht immer richtig pythonisch denke, sondern immer noch von anderen Sprachen beeinflußt bin, hast Du wahrscheinlich recht. Ich will mich wohl immer noch nicht voll und ganz auf Python einlassen. Eigentlich ist C wohl mein Ideal; leider ist es eher eine Haßliebe. Wenn ich versuche, mich C zu nähern, kommt als schroffe Antwort meist nur "Speicherzugriffsfehler". ;)

@All: Wenn man eine "for-Schleife" macht

Code: Alles auswählen

for i in range(15):
drückt man doch eher aus: Bitte versuche 15 mal, eine Primzahl zu finden. Erst eine (ein Schleifendurchlauf), dann noch eine, usw.. Wahrscheinlich könnte man das mit Mühe auch so umsetzen, aber näher an dem, was man eigentlich sagen will, ist doch "while". Also:
Ich habe keine Ahnung, wie groß die 15. Primzahl sein wird. Bitte fange einfach bei 2 an zu zählen und prüfe eine Zahl nach der anderen. Wenn Du dabei eine Primzahl findest, merke Dir das bitte. Sobald Du die 15. gefunden hast, höre bitte auf, weiterzuzählen.
Warum hat Arturs Lehrer wohl diese Aufgabe gestellt, genau 15 Zahlen zu finden? Ich meine, er will "while" sehen. Die Schüler sollen genau in die Problemlage kommen, die Artur hatte "aber ich bin mit 'for' ja davon abhängig, daß ich nur bis 60 (oder bis woauchimmer) zähle. Das muß ich irgendwie anders machen."
Hier also mein Codevorschlag:

Code: Alles auswählen

#!/usr/bin/env python
# coding: iso-8859-1

l = [2]
num = 2
while len(l) < 15:
    isprim = True
    for i in l:
        if not num % i:
            isprim = False
            break
    if isprim:
        l.append(num)
    num += 1

for i in range(len(l)):
    print str(i + 1) + ". " + str(l[i])
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

problembär hat geschrieben:

Code: Alles auswählen

#!/usr/bin/env python
# coding: iso-8859-1

l = [2]
num = 2
while len(l) < 15:
    isprim = True
    for i in l:
        if not num % i:
            isprim = False
            break
    if isprim:
        l.append(num)
    num += 1

for i in range(len(l)):
    print str(i + 1) + ". " + str(l[i])
Warum fängst du mit l = [2] an und nicht mit l = []? Das würde mir logischer erscheinen.
Ungetestet:

Code: Alles auswählen

l = []
num = 2
while len(l) < 15:
    if all(num % p for p in l): 
        l.append(num)
    num += 1
BlackJack

@problembär: Eine ``for``-Schleife die 15-mal durchlaufen wird hat hier niemand vorgeschlagen.

Dein Argument das ``while`` näher an dem ist wie Du das in dem Zitat ausdrückst, kann ich nicht nachvollziehen. Im Gegenteil; bei ``Bitte fange einfach bei 2 an zu zählen und prüfe eine Zahl nach der anderen. […] Sobald Du die 15. gefunden hast, höre bitte auf, weiterzuzählen.`` denke ich nicht an ``while`` sondern an ``for``. Das steht doch für jede Zahl ab 2 prüfe [̣…] brich ab wenn 15 Treffer. Das ist eine ``for``-Schleife über die Zahlen ab 2 und ein ``break`` für den Abbruch.

Selbst wenn der Lehrer davon ausgeht, dass die meisten `itertools.count()` nicht kennen, sollte es für eine ``for``-Schleife damit keinen Abzug geben. Wenn nicht ``while`` explizit vorgegeben ist, kann er sich nicht beschweren wenn jemand eine passendere, weniger fehleranfällige, einfachere Formulierung mit ``for`` abliefert.

Deine letzte ``for``-Schleife lässt mich dann noch daran zweifeln ob Du tatsächlich anderen Leuten Ratschläge für Python-Programme geben solltest. *Das* Anti-Pattern überhaupt im Zusammenhang mit ``for``-Schleifen. Wenn Du das Konzept von Iteratoren nicht magst, solltest Du gänzlich auf ``for`` verzichten, denn das ist nun einmal die Grundlage einer *jeden* ``for``-Schleife in Python. Die `str()` und das ``+`` ist auch eher BASIC als Python.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@bords0: Ist das ein definiertes Verhalten?

Code: Alles auswählen

In [22]: all([])
Out[22]: True
Ich hätte da jetzt Zweifel...

@problembär: Wieso muss man eine Liste `l` nennen? Mit `i` kann man ja grad noch leben, aber der Resultatmenge kann man doch gerne mal einen aussagekräftigen Namen spendieren - und das ist ja nun wirklich unabhängig von Vorlieben oder anderen Sprachen (C64 Basic mal ausgenommen :twisted: ).

Und das englische Wort für "prim" ist (mutually) "prime" - "prim" (engl.) hat andere Bedeutungen - SCNR ;-)

Generell ist Dein Ansatz natürlich auch richtig, aber Du siehst hoffentlich, dass BlackJacks Lösung viel sauberer und lesbarer ist? Bei Deiner Lösung muss man neben den Initialisierungen vor allem das Flag "isprim" erst richtig interpretieren bzw. dessen Status "verfolgen". Zudem ermöglicht es der Ansatz mit `all`, dass man "positiv" auf eine Primzahl testet; damit kann man direkt beim Erfolg die Zahl an die Liste hängen und muss eben nicht erst nach der Schleife prüfen, ob das ganze erfolgreich war.

Kurz noch als letztes: Gewöhne Dir doch aber wenigstens mal an, Strings richtig zu konkatenieren! Dieses " " + " " + " " + ... Gefrickel liest sich ja furchtbar. Außerdem kann man über ein Iterable immer direkt iterieren!

Code: Alles auswählen

# grausam, wirklich grausam!
for i in range(len(l)):
    # naja... eher häßlich
    print str(i + 1) + ". " + str(l[i])
# so gehts doch hübscher, leichter und lesbarer
for index, value in enumerate(l, 1):
    print("{}. {}".format(index, value))
Ok, BlackJack war schneller - nuja, ich hab einiges aber expliziter aufgeschrieben, daher lasse ich es mal stehen :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hyperion hat geschrieben:@bords0: Ist das ein definiertes Verhalten?

Code: Alles auswählen

In [22]: all([])
Out[22]: True
Ich hätte da jetzt Zweifel...
Ok, ein Blick in die Doku hilft eben doch manchmal:
Return True if all elements of the iterable are true (or if the iterable is empty).
:oops:

Ausrede:
Ich hatte nur in der Shell den Docstring aufgerufen und da fehlt diese Info leider :!:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Was sollte denn sonst das Ergebnis sein? Dass nicht alle Elemente einer leeren Liste wahr sind? Welches denn z.B.? :wink:
problembär

Hyperion hat geschrieben:Generell ist Dein Ansatz natürlich auch richtig, aber Du siehst hoffentlich, dass BlackJacks Lösung viel sauberer und lesbarer ist?
Durchaus nicht. Lauter unnötiges Modul-Gefrickel dort. Als Vorschlag für einen Programmieranfänger total ungeeignet. Arturs Lehrer wird das auch nicht verstehen und sich darüber wundern, weil er stattdessen eine einfache 'while'-Schleife erwartet.
BlackJack sollte davon absehen, Anfängern, bzw. überhaupt jemandem Ratschläge zu Python zu geben, weil er zwar möglicherweise irgendwelchen Modul-Hokuspokus betreiben kann, aber dabei in keiner Weise auf die Bedürfnisse der Fragesteller eingeht.
Hyperion hat geschrieben:Gewöhne Dir doch aber wenigstens mal an, Strings richtig zu konkatenieren! Dieses " " + " " + " " + ... Gefrickel liest sich ja furchtbar.
Die Strings sind so richtig konkaterniert!
Das ist so auch viel lesbarer als dieser '" ".join()'-Schwachsinn, den jedenfalls kein Anfänger versteht, während bei "+" sofort klar ist, was gemeint ist.
Wenn das nicht so wäre, gäbe es den +-Operator für Strings überhaupt nicht.
BlackJack hat geschrieben:Deine letzte ``for``-Schleife lässt mich dann noch daran zweifeln ob Du tatsächlich anderen Leuten Ratschläge für Python-Programme geben solltest. *Das* Anti-Pattern überhaupt im Zusammenhang mit ``for``-Schleifen. Wenn Du das Konzept von Iteratoren nicht magst, solltest Du gänzlich auf ``for`` verzichten, denn das ist nun einmal die Grundlage einer *jeden* ``for``-Schleife in Python.
Blödsinn. Ich brauche hier die Elemente der Liste selbst und zugleich die Stellen, an denen sich die Elemente befinden.

Code: Alles auswählen

for i in range(len(l)):
ist dafür der einfachste, schnellste und beste Weg. Der auch weder irgendeinen Fehler, noch eine Warung des Interpreters hervorruft, also in jeder Hinsicht zulässig ist.
Es gibt keinen vernünftigen Grund, darauf zu verzichten. Ihr verbietet euch selbst und anderen immer wieder brauchbare und sinnvolle Konzepte, allein aufgrund einer völlig verqueren Ideologie.
Die es noch nicht einmal gibt, sondern die ihr euch nur einbildet. Sehr armselig. Auf so einen Unsinn wie dieses Forum kann ich gut verzichten.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

problembär hat geschrieben: Durchaus nicht. Lauter unnötiges Modul-Gefrickel dort. Als Vorschlag für einen Programmieranfänger total ungeeignet.
Sehe ich nicht so. Aber vielleicht täusche ich mich auch - jedenfalls bist Du sicher nicht qualifizierter als wir, das zu beurteilen.
problembär hat geschrieben: Arturs Lehrer wird das auch nicht verstehen und sich darüber wundern, weil er stattdessen eine einfache 'while'-Schleife erwartet.
Das ist ja weder Arturs noch unser Problem ;-)
problembär hat geschrieben: BlackJack sollte davon absehen, Anfängern, bzw. überhaupt jemandem Ratschläge zu Python zu geben, weil er zwar möglicherweise irgendwelchen Modul-Hokuspokus betreiben kann, aber dabei in keiner Weise auf die Bedürfnisse der Fragesteller eingeht.
Na, da sei aber Gott vor! Ich habe so viel von ihm gelernt und lerne immer noch gerne etwas dazu. Im Gegensatz zu Dir, wie es scheint. Wieso beharrst Du auf so dämlichen Konstrukten wie Deiner `for i in range(len(iterable))` Schleife?
problembär hat geschrieben: Die Strings sind so richtig konkaterniert!
Das ist so auch viel lesbarer als dieser '" ".join()'-Schwachsinn, den jedenfalls kein Anfänger versteht, während bei "+" sofort klar ist, was gemeint ist.
Wenn das nicht so wäre, gäbe es den +-Operator für Strings überhaupt nicht.
Nur weil es ihn gibt, heißt das nicht, dass das der bevorzugte Weg sein sollte, Strings zu konkatenieren! In C geht das im übrigen auch nicht, sondern ähnelt eher der `format`- oder auch der `%`-Methodik wo Du doch sonst immer so C-esquen Code schreibst... ;)
problembär hat geschrieben: Blödsinn. Ich brauche hier die Elemente der Liste selbst und zugleich die Stellen, an denen sich die Elemente befinden.

Code: Alles auswählen

for i in range(len(l)):
ist dafür der einfachste, schnellste und beste Weg. Der auch weder irgendeinen Fehler, noch eine Warung des Interpreters hervorruft, also in jeder Hinsicht zulässig ist.
Unsinn! `enumerate` ist der offensichtliche Weg! Damit hast Du einen (frei definierbaren) Index und das Element - besser geht es nicht. Zudem brauchst Du beim Zugriff kein hässliches und verworrenes Index-Gefummel.

Bei Dir hat man das Gefühl, dass Du auf so ziemlich jedes Built-in verzichten willst, weil es zu "kompliziert" ist. Aber genau diese Built-ins machen doch eine Sprache erst aus. Oder nutzt Du in C auch keine Built-ins? Python kommt natürlich mit einer Vielzahl an Modulen und natürlich kann man als Einsteiger nicht alle nützlichen Funktionen kennen, aber spätestens, wenn man darauf hingewiesen wird, sollte man die sich mal ansehen und sich damit befassen. Dank der exzellenten Doku sind die meisten Dinge dann schnell zu begreifen. Das ist einzig eine Frage der Einstellung und nicht de facto zu schwierig für Einsteiger (oder Hinweis-Verweigerer).

Ich gebe Dir sogar recht, dass ein Einsteiger vermutlich so eine Schleife schreiben würde, oder noch schlimmer mit einer Zählvariable arbeiten würde, aber spätestens nach einem Hinweis auf die Existenz von `enumerate` würde er einfach darauf umsteigen. Genau das nennt man "lernen". Genauso verhält es sich mit `itertools.count` - was ist daran so schwer zu kapieren? Du musst nicht mal das Konzept von Generatoren verstanden haben, sondern nur "akzeptieren", was das Ding macht.

Du bist es eben von C gewöhnt, mit Indexen in for-Schleifen zu arbeiten. Aber Python ist eben nicht C (ein Glück!). Nebenbei kommen Schleifen, die über Elemente und nicht nur Indexe iterieren können immer mehr in Mode. Auch Java ist dadurch seit Version 5 benutzbarer geworden und JavaScript bietet das afaik auch erst seit kurzem.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Hyperion: C kann er doch auch nicht. Ich glaube er trollt hier einfach nur herum mit Code von dem er genau weiss, dass es eben kein idiomatisches Python ist.
Benutzeravatar
pillmuncher
User
Beiträge: 1530
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

problembär hat geschrieben:
Hyperion hat geschrieben:Gewöhne Dir doch aber wenigstens mal an, Strings richtig zu konkatenieren! Dieses " " + " " + " " + ... Gefrickel liest sich ja furchtbar.
Die Strings sind so richtig konkaterniert!
Das ist so auch viel lesbarer als dieser '" ".join()'-Schwachsinn, den jedenfalls kein Anfänger versteht, während bei "+" sofort klar ist, was gemeint ist.
Wenn das nicht so wäre, gäbe es den +-Operator für Strings überhaupt nicht.
Das hier steht auf wiki.python.org
Das steht auf Starship Python
Das hier lernt man in der University of Colorado in Boulder
Und hier hat jemand einen Performance-Vergleich angestellt.
problembär hat geschrieben:
BlackJack hat geschrieben:Deine letzte ``for``-Schleife lässt mich dann noch daran zweifeln ob Du tatsächlich anderen Leuten Ratschläge für Python-Programme geben solltest. *Das* Anti-Pattern überhaupt im Zusammenhang mit ``for``-Schleifen. Wenn Du das Konzept von Iteratoren nicht magst, solltest Du gänzlich auf ``for`` verzichten, denn das ist nun einmal die Grundlage einer *jeden* ``for``-Schleife in Python.
Blödsinn. Ich brauche hier die Elemente der Liste selbst und zugleich die Stellen, an denen sich die Elemente befinden.

Code: Alles auswählen

for i in range(len(l)):
ist dafür der einfachste, schnellste und beste Weg. Der auch weder irgendeinen Fehler, noch eine Warung des Interpreters hervorruft, also in jeder Hinsicht zulässig ist. Es gibt keinen vernünftigen Grund, darauf zu verzichten.
Wie wär's mit diesem:

Code: Alles auswählen

Iterating through an array
Python's for statement is not like C's; it's more like a "foreach" statement in some other languages. If you need to use the loop index explicitly, the standard way is like this:

    array = [1, 2, 3, 4, 5]  # or whatever

    for i in range(len(array)):
        # Do something with 'i'.

This is quite clumsy. A somewhat cleaner way to do this is:

    array = [1, 2, 3, 4, 5]  # or whatever

    for i, e in enumerate(array):
        # Do something with index 'i' and its corresponding element 'e'.
Zu finden auf der CalTech-Website
problembär hat geschrieben:Ihr verbietet euch selbst und anderen immer wieder brauchbare und sinnvolle Konzepte, allein aufgrund einer völlig verqueren Ideologie.
Die es noch nicht einmal gibt, sondern die ihr euch nur einbildet. Sehr armselig.
Das, was wir propagieren ist nicht ideologisch, sondern idiomatisch. In Python programmiert man eben so. Du willst es bloß nicht lernen, weil du meinst, Grundkenntnisse in C, Pascal, oder welch paläolithischer Programmiersprache auch immer, würden schon genügen, um damit durchzukommen. Ebenso ist dein Hinweis auf "Modul-Gefrickel" einfach nur lachhaft. Klar, jeder Landwirt züchtet die Ochsen selber, die seinen Pflug ziehen, und jeder Optiker hat im Keller einen Schmelzofen in dem er aus Quarzsand, Soda und Pottasche Glas für seine Brillen herstellt, und jeder Programmierer ingoriert die Standard-Bibliothek seiner Programmiersprache und wurstelt auf der niedrigsten Abstraktionsebene alles selber zusammen. Letztes Jahr hab ich mit solchen Leuten zusammenarbeiten müssen. Einer hat allen Ernstes in geschachtelten Schleifen mittels "+" XML-Dateien erzeugt. Nachdem ich das gesehen hatte, hätte ich mir wieder mal am liebsten die Augen mit Kernseife ausgewaschen.
problembär hat geschrieben:Auf so einen Unsinn wie dieses Forum kann ich gut verzichten.
Na dann: Servus. Einer weniger, der die n00bs verdirbt.
In specifications, Murphy's Law supersedes Ohm's.
Antworten