Neuling in Python

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.
Benutzeravatar
NoPy
User
Beiträge: 158
Registriert: Samstag 28. Dezember 2013, 12:39

bwbg hat geschrieben:Ergänzend hierzu:

Code: Alles auswählen

>>> ()
()
>>> type(())
<class 'tuple'>
Hier bildet () ein leeres Tupel.
Hab es jetzt ausprobiert, da ist er wieder, mein persönlicher HÄ?- Effekt

Warum bilden
(1,2,3) und (1,2) Tupel
(1) kein Tupel
() wieder Tupel?

Kann man lernen, ohne Zweifel. Aber ist für mich schon überraschend
Zuletzt geändert von NoPy am Donnerstag 5. November 2015, 16:30, insgesamt 2-mal geändert.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

/me hat es schon gesagt: Tupel werden durch das Komma erzeugt, nicht durch die Klammern.
Damit hat man aber das Problem, dass man so keine Leeren Tupel erzeugen kann. So kommt es zum Sonderfall `()` fuer das leere Tupel (und wahrscheinlich zur irrigen Annahme, dass Tupel durch Klammern erzeugt werden).
Benutzeravatar
NoPy
User
Beiträge: 158
Registriert: Samstag 28. Dezember 2013, 12:39

Nun gut, formuliere ich die Frage um:
Es gibt 2- elementige Tupel, 3- elementige Tupel ...

Irgendjemand benötigte auch mal ein 0- elementiges Tupel. Wofür?

Was passiert, wenn jemand ein 1- elementiges Tupel benötigt? Wie wird das definiert?

Beispiel:

Code: Alles auswählen

def SchreibDasAuf(a):
    for zeile in a:
        for element in zeile:
            print element

a = [[],[1],[1,2],[1,2,3],[1,2,3,4]]
b = ((),(1),(1,2),(1,2,3),(1,2,3,4))
SchreibDasAuf(a)
SchreibDasAuf(b)
Zuletzt geändert von NoPy am Donnerstag 5. November 2015, 16:40, insgesamt 1-mal geändert.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

1-elementige Tupel hat /me doch gezeigt.

Warum 0-elementige? Haeufig wird man sie nicht brauchen, aber auch ueber 0-elementige Tupel kann man iterieren:

Code: Alles auswählen

In [2]: for x in ():
   ...:     print x
   ...:
So braucht man keinen Spezialfall in dem Man zb eine Leere Liste statt einem Tupel benutzt.
Ehrlich gesagt kann ich mir momentan nur einen Nutzen als Default-Argument fuer Funktionnen vorstellen (und auch dort ist es zwingend noetig).
Benutzeravatar
NoPy
User
Beiträge: 158
Registriert: Samstag 28. Dezember 2013, 12:39

ah, überlesen.

also
a3 = (1,2,3)
a2 = (1,2)
a1 = (1,)
a0 = ()

Nun ja ... kann man lernen
BlackJack

Leere Tupel kann man auch brauchen wenn man eine leere Sequenz benötigt aber Listen dafür nicht gehen, zum Beispiel weil Listen nicht „hashable“ sind und damit nicht als Schlüssel in Wörterbüchern oder als Elemente in Mengen verwendet werden können. Zum Beispiel wenn man ein Wörterbuch hat das Wege auf Kosten abbildet und ein Weg dabei durch eine Sequenz von Wegpunkten/Knoten beschrieben wird, dann möchte man vielleicht auch so etwas wie ``path2cost[()] = 0`` haben ohne das als Sonderfall behandeln zu müssen.
Benutzeravatar
kbr
User
Beiträge: 1507
Registriert: Mittwoch 15. Oktober 2008, 09:27

NoPy hat geschrieben:a3 = (1,2,3)
a2 = (1,2)
a1 = (1,)
a0 = ()
Die Klammern brauchst Du nur für den Sonderfall a0. Das Komma als Tuplekonstruktor ermöglicht auch so schöne Sachen wie

a, b = b, a
Benutzeravatar
pillmuncher
User
Beiträge: 1530
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

NoPy hat geschrieben:Nun gut, formuliere ich die Frage um:
Es gibt 2- elementige Tupel, 3- elementige Tupel ...

Irgendjemand benötigte auch mal ein 0- elementiges Tupel. Wofür?
Abgesehen von der Hashbarkeit: Tupel bilden ein Monoid. Dazu benötigt man neben einer assoziativen Verkettungsoperation ( + bei Tupeln) auch ein Identitätselement und das ist das leere Tupel:

Code: Alles auswählen

In [1]: #Assoziativität:

In [2]: assert ((1,2) + (3,4)) + (5,6) == (1,2) + ((3,4) + (5,6)) == (1,2,3,4,5,6)

In [3]: #Identitätselement:

In [4]: assert () + (1,2,3) == (1,2,3) + () == (1,2,3)
Und hier sieht man, wofür man Klammern bei Tupeln braucht:

Code: Alles auswählen

In [5]: (1,2) + (3,4)
Out[5]: (1, 2, 3, 4)

In [6]: 1,2 + 3,4
Out[6]: (1, 5, 4)
Um es nochmal zu betonen: Bei der literalen Notation im Pythoncode ist das Komma der Tupel-Operator. Die Klammern dienen lediglich zur Disambiguierung. Ausnahme: das leere Tupel wird durch ein leeres Paar Klammern notiert. Man könnte es auch ohne literale Notation so schreiben:

Code: Alles auswählen

In [7]: tuple()
Out[7]: ()
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
NoPy
User
Beiträge: 158
Registriert: Samstag 28. Dezember 2013, 12:39

Euch mögen meine Fragen blöd vorkommen, aber Eure Antworten helfen mir. Daher werde ich auch nicht damit aufhören ;)
Vielen Dank für die umfangreichen Erläuterungen.

Wenn der ","- operator Tupel- bildend ist, wie muss man denn dann das Komma innerhalb einer Liste interpretieren?

Code: Alles auswählen

a = (1,2,3)
b = 1,2,3
a == b #True

c = [(1,2,3)]
d = [1,2,3]
c == d #False

Wenn die Klammerung im ersten Fall (a,b) egal war, so ändert sie im zweiten Fall sehr wohl den Sachverhalt.
c ist eine Liste mit einem Tupel, d ist eine Liste mit 3 Integern.
Der einzige Unterschied ist die Klammer, die bei a und b egal war und hinsichtlich der Tupel- Bildung keine Bedeutung haben soll.

Ich bin sicher, Du hast eine Erklärung, bin schon neugierig, welche :)
Benutzeravatar
kbr
User
Beiträge: 1507
Registriert: Mittwoch 15. Oktober 2008, 09:27

Steigen wir in die banalen Niederungen der Schulmathematik mit der bekannten Regel: Punktrechnung vor Strichrechnung. In Pillmunchers Beispiel galt Strichrechung vor Tupelkonstruktor. D.h. der arithmetische Plus-Operator hatte die stärkere Bindung. Daher waren die Klammern erforderlich, um diese Bindung zu umgehen.
In dem Listenbeispiel ist es ähnlich: in einer Liste werden Elemente durch Kommata getrennt. Diese Regel hat eine stärkere Bindung als der Tupelkonstruktor. Daher benötigte Du Klammern in einer Liste um Tupel anzulegen.
Benutzeravatar
pillmuncher
User
Beiträge: 1530
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@NoPy: Es ist in Python einfach so festgelegt. Kommata dienen als Separatoren, bei Funktionsdefinitionen und -aufrufen, bei Vererbungsdeklarationen in class Statements und in literalen Listen-, Mengen- und Ditionary-Ausdrücken und vermutlich noch an anderen Stellen, die mir gerade nicht einfallen . Nur bei Tupeln dienen sie zudem noch als Konstruktionsmerkmal, außer beim leeren Tupel. Die runden Klammern sind syntaktisch optional, nur semantisch gibt es dann einen Unterschied, wenn der geklammerte Ausdruck etwas anderes bedeutet, als der unkeklammerte. Beispiel:

Code: Alles auswählen

In [1]: 3 * 4 + 5 == 3 * (4 + 5)
Out[1]: False
Literale Listenausdrücke sind einfach Ausdrücke, die mit einem [ starten, gefolgt von Null oder mehr durch Komma getrennte beliebige Ausdrücke, gefolgt von einem ]. Ein mit runden Klammern geklammerter Ausdruck ist ein Ausdruck, selbst wenn darin wieder Kommata vorkommen. Eine Liste wie [(1,2,3)] ist daher eine Liste mit einem Tupel als einzigem Element, [1,2,3] eine Liste mit drei Elementen.

Ich fand das alles immer sehr intuitiv und habe mir nie groß Gedanken darüber gemacht. Es hat einfach alles immer so funktioniert, wie ich das erwartet habe.
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
kbr
User
Beiträge: 1507
Registriert: Mittwoch 15. Oktober 2008, 09:27

pillmuncher hat geschrieben:Ich fand das alles immer sehr intuitiv und habe mir nie groß Gedanken darüber gemacht. Es hat einfach alles immer so funktioniert, wie ich das erwartet habe
Das geht mir auch so und vermeintlich einfache Fragen sind in dieser Hinsicht oft recht interessant.
Benutzeravatar
NoPy
User
Beiträge: 158
Registriert: Samstag 28. Dezember 2013, 12:39

In der Tat hatte ich von Listen und Tupeln bislang falsche Vorstellungen.
Im Grunde dachte ich immer, der wesentliche Unterschied läge darin, dass Listen erweiterbar sind und Tupel nicht.
Dank Eurer Erklärung sehe ich das nun klarer.

Code: Alles auswählen

a = [[[[1]]],2]
b = ((((1))),2)
c = ((((1,),),),2)
Um das aus a mit Tupeln auszudrücken, ist nicht die Definition von b richtig, sondern die von c
Wäre mir vorher nicht bewusst gewesen und ich bin mir sicher, dass sich einige meiner Irrtümer seit python- Start sich darauf zurückführen lassen.

Also wieder: Vielen Dank
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Um, Unveraenderlichkeit _ist_ der wesentliche Unterschied zwischen Listen und Tupeln. Was hat du aus den Posts denn jetzt anderes herausgelesen?

Dass Tupel zB Hashbar sind ist ja eine Folge davon, dass sie unveraenderlich sind (Hash repraesentiert ja den Inhalt, das geht aber nicht vernuenftig, wenn der sich veraendern kann).
Benutzeravatar
NoPy
User
Beiträge: 158
Registriert: Samstag 28. Dezember 2013, 12:39

cofi hat geschrieben:Um, Unveraenderlichkeit _ist_ der wesentliche Unterschied zwischen Listen und Tupeln. Was hat du aus den Posts denn jetzt anderes herausgelesen?
Dass die Definition bei Tupeln durch die Kommata erfolgt, welche hingegen bei Listen eine völlig andere Bedeutung haben, deren Definition durch Klammern gegeben ist. Entsprechend ist die Syntax von Konstanten - insbesondere von Listen von Listen von Listen völlig unterschiedlich.

Der Unterschied ist für mich nicht weniger wesentlich, insbesondere daher, dass ja Tupel im Grunde nur durch Konstanten definierbar sind.
Solange ich Tupel benutze, die mindestens 2 Elemente haben, fällt mir das nicht auf. Wenn ich aber genau 1 habe - und dieser Umstand ist häufiger, als oberflächlich betrachtet, unterscheidet sich die Syntax sehr. Darauf bin ich definitiv schon hereingefallen.

a = [[[[1]]]] ist eine Liste von Listen von Listen von Listen von Integer, wobei jede dieser verschachtelten Listen genau 1 Element enthält.
Wenn ich irgendwelche Strukturen dieser Art zusammengebastelt habe (gut, meist waren es weniger "Etagen"), dann habe ich - wenn ich zum Test Konstanten verwendet habe - das immer mit Tupeln abgebildet (logischerweise). Solange meine Tests auch je Zeile immer mindestens 2 Elemente hatten, war es kein Problem. Mein Hä?- Effekt kam offensichtlich immer an solchen Stellen. Irgendwann habe ich dann doch Listen verwendet, weil es irgendwie besser lief, auch wenn ich es mir nicht erklären konnte.
Aber ich hätte einfach nur
a = ((((1,),),),) schreiben müssen.

Tut mir leid, aber mich hat das verwirrt.
Vielleicht wäre es für die Sprache von Vorteil, das abschließende Komma für alle Tupel zu erzwingen, nicht bloß für einelementige. Aber das ist eine fruchtlose Diskussion. Ich weiß es nun und vielleicht liest jemand mit einem ähnlichen Verständnisproblem ja mal diesen Thread ...

Vielleich noch mal zur Erklärung: Ich habe häufig mit Geographischen Informationen zu tun. Zum Teil sind die Objekte, die ich bekomme, schon so oder so ähnlich, zum Teil lohnte es scheinbar nicht, aus den Zwischenebenen Klassen zu machen, da sie letztlich dumm waren und eigentlich nur ein getter und setter brauchten. Und so kamen schnell mal Listen von Listen... zusammen
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Wenn du viele 1-elementige Tupel hast, machst du IMO etwas falsch.

Tupel benutzt man wenn man eine Reihe von Objekten hat und jede Position eine bestimmte Bedeutung hat. Bspw `person = "Fritz", "Mueller", 42`
In dem Sinn sind `namedtuple` prototypische Tupel (nur gibt es Tupel schon viel laenger).
Wenn du jetzt also 1-elementige Tupel benutzt hast du im Grunde nur eine unnoetige Schicht herum gelegt.

Listen dagegen benutzt man wenn man eine Reihe von Objekten hat in der die Reihenfolge zwar moeglicherweise wichtig ist, aber nicht jede Position Sinn belegt.

Die Ausnahme sind natuerlich Situationen in denen man die Hashbarkeit braucht wie bei Pfaden in BlackJacks Beispiel.
doclektor
User
Beiträge: 10
Registriert: Mittwoch 28. Oktober 2015, 04:37

Danke euch für die Antworten.
Im Augenblick verwirrt mich das alles noch.
Deshalb möchte ich mal so fragen. (Ist wahrscheinlich für mich einfacher weil ich mir dann explizit die Informationen dazu Suchen kann.

Wie gebe ich die Vereine ein (Liste, Tabelle ?)
Wo mit erstelle ich die Tabelle
müsste ja so aussehen:
Platz Verein Spiele G U V Punkte Tordifferenz
Wo mit gebe ich die Spieltage ein und generiere alle Spieltage.
Ich glaube das reicht erst mal, kommt ja noch genug.

Es brauchen keine Lösungen sein, sondern nur die Information mit welchen Funktionen ich diese Sachen erstellen kann.

Vielen Dank
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Naja das kommt alles darauf an, _wie_ du das machen willst.

Zum Beispiel kannst du das alles direkt in Python schreiben:

Code: Alles auswählen

TEAMS = ["FC Blau-Weiss", "SC Gruen-Rot", ...]
DAYS = 4
...
Damit koennte man dann den Spielablaufplan generieren und auch Formulare fuer die Spielstaende.
Mit letzterem kommst du dann an alle Informationen fuer die Tabelle.

Mal ein kleines Beispiel wie man zb den Teilaspekt der Tordifferenz modellieren kann:

Code: Alles auswählen

from collections import namedtuple
Game = namedtuple("Game", ['teams', 'goals'])
class Team(object):
    def __init__(self, name):
        self.name = name
        self.games = []
        
    def add_game(self, game):
        self.games.append(game)
        
    def goal_difference(self):
        shot, received = 0, 0
        for game in self.games:
            for team, goals in zip(game.teams, game.goals):
                if team == self.name:
                    shot += goals
                else:
                    received += goals
        return shot, received        
  
team = Team("FCBW")
team.add_game(Game(('FCBW', 'Other'), (1, 3)))
team.add_game(Game(('FCBW', 'Other2'), (3, 1)))
print team.goal_difference()
# (4, 4)
Aber konkrete Hilfe koennen wir erst geben, wenn du sagen kannst, wie es bedient werden soll. Nur "kundige" Anwender? Laufend aktualisiert? Etc, Etc.
Benutzeravatar
NoPy
User
Beiträge: 158
Registriert: Samstag 28. Dezember 2013, 12:39

Also ich denke, ich werde keinen Widerspruch ernten, wenn ich sage, dass eine Oberflächenentwicklung unter python für einen Neuling eher ungeeignet ist.
Daher benötigst Du im Grunde alternative Ein- und Ausgabe- Wege.
Gehen wir mal davon aus, dass auf dem Rechner, auf dem das ganze mal laufen soll, auch python installiert ist.
Dann wäre es m.E. sinnvoll, Bibliotheken/Module/Klassen so zu schreiben, dass Du wahlweise den Import von Hand erledigen kannst
Beispiele:

Code: Alles auswählen

Teams = (('BFC Dynamo', 'BFC'), ('Dynamo Dresden', 'DynDD'), ('1. FC Carl Zeiss Jena', 'Jena'), ('1. FC Magdeburg', 'FCM'), ('FC RotWeiß Erfurt','RWE'))
MeineSpielMatrix = SpielMatrix(Teams)
MeineSpieltage = Spieltage(MeineSpielMatrix)
MeineTabelle = Tabelle(MeineSpielMatrix)
MeinErgebnis = Ergebnis('DynDD','BFC','10:1')

MeineSpielMatrix.Aktualisiere(MeinErgebnis)
MeineSpieltage.Aktualisiere(MeinErgebnis)
MeineTabelle.Aktualisiere(MeinErgebnis)

MeineSpielMatrix.Speichere('Tabelle.txt') 
MeineSpieltage.Speichere('Tabelle.txt') 
MeineTabelle.Speichere('Tabelle.txt') 
Halte ich aber für suboptimal, da das ganze doch recht steif ist.
M.E. solltest Du eine Klasse bauen, die mit den Teams initialisiert werden kann, wahlweise über Liste/Wörterbuch/Datei
Diese Klasse sollte dann die Methoden bereitstellen, die Du benötigst, um
- zu laden
- zu speichern
- zu aktualisieren (Ergebnisse einzutragen)
- Reporte zu erstellen

Das ganze solltest Du in Teile aufteilen und dann zum Schluss zusammenbauen

Die Eingabe der Ergebnisse könntest Du dann auch entweder über die Konsole oder über eine Eingabedatei machen
Das alles dann gegen Fehleingaben zu sichern ist sicher mit Arbeit verbunden ...
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

@doclektor:

Auf die Gefahr hin, dass auch ich mit Steinen beworfen werde, empfehle ich Dir, Dich einmal mit dem Calculationsprogramm von OpenOffice (CALC) zu beschäftigen. Damit hast Du schon einmal eine Tabelle und OpenOffice unterstützt Python. Du brauchst also nicht einmal Python zu installieren. Du kannst aber auch auf Python zunächst einmal verzichgten und alles mit dem OpenOffice-Basic machen.

Hier, den Eindruck habe ich, gibt es sehr viele Python-Spezialisten, die den den Bezug zum Status eines Python-Anfägers, oder besser gesagt, eines Python-Interessierten, verloren haben und sich mit einer wahnsinnigen Begeisterung vorwiegend mit sich selbst beschäftigen. Du und Dein Problem bist schon vergessen, wie gesagt, das ist mein Eindruck.

MfG, kodela
Antworten