Slices bis zum Anfang

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
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

Ausgehend von einem Tupel

Code: Alles auswählen

prim = (2,3,5,7,11,13,)

kann ich in Python3 mit Hilfe von Slices alle Schleifen

Code: Alles auswählen

for p in prim[5,4,-1]: pass  #p in (13,)
for p in prim[5,3,-1]: pass  #p in (13,11,)
for p in prim[5,2:-1]: pass  #p in (13,11,7,)
for p in prim[5,1:-1]: pass  #p in (13,11,7,5,)
for p in prim[5,0:-1]: pass  #p in (13,11,7,5,3,)
ausführen außer

Code: Alles auswählen

for p in prim[?:?:?]: pass  #p in (13,11,7,5,3,2,)
was mir irgendwie lächerlich vorkommt. Geht es wirklich nicht oder bin ich nur ungeschickt?
Sirius3
User
Beiträge: 17745
Registriert: Sonntag 21. Oktober 2012, 17:20

@Goswin: Die Slice-Notation sagt Start:Ende:Schrittweite, wobei Ende nicht mitgenommen wird. Also wenn Du bis zum 0-ten Element gehen willst, muß Ende eins weiter gezählt werden, was -1 wäre, das entspricht aber dem vorletzten Element :cry: . Lösung, einfach weglassen, also: prim[5::-1]
eckhard
User
Beiträge: 33
Registriert: Montag 14. Dezember 2015, 10:06
Wohnort: Karlsruhe

Hallo Goswin,

ist

Code: Alles auswählen

for p in prime[5::-1]: pass
das was Du suchts?

eckhard

Sirius hatte schon drei Minuten vor mir dir richtige Antwort, die ich beim Schreiben meiner Antwort nicht kannte.
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

:D Danke, das war es, was ich suchte; auf die Weglassen-Idee bin ich einfach nicht gekommen!
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Erwaehnen sollte man noch, dass das nicht nach dem richtigen Einsatz von Tupeln aussieht. Wenn du tatsaechlich nicht die unveraenderbarkeit brauchst, dann sollte das eine Liste sein.
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

cofi hat geschrieben:Erwähnen sollte man noch, dass das nicht nach dem richtigen Einsatz von Tupeln aussieht. Wenn du tatsächlich nicht die Unveränderbarkeit brauchst, dann sollte das eine Liste sein.
Interessant, ich hatte das bisher genau umgekehrt gesehen:
Wenn ich auf die Veränderbarkeit irgendwie verzichten kann, dann (dachte ich) sollte ich Tupel vorziehen, weil diese "hinter den Kulissen" irgendwie einfacher als Listen zu behandeln sind. Ist das nicht so?
BlackJack

@Goswin: Die übliche Konvention ist es Tupel für Informationen zu verwenden wo jeder Index eine Bedeutung hat, das heisst die Werte unterschiedliche Bedeutungen haben, und Listen wo der Wert an jedem Index die gleiche Bedeutung hat. Und die Bedeutung eines jeden Elements in Deinem Beispiel ist „Primzahl“.
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

BlackJack hat geschrieben:@Goswin: Die übliche Konvention ist es Tupel für Informationen zu verwenden wo jeder Index eine Bedeutung hat, das heisst die Werte unterschiedliche Bedeutungen haben, und Listen wo der Wert an jedem Index die gleiche Bedeutung hat.
Gibt es irgend einen triftigen Grund für diese Konvention? (Der Ausdruck "Konvention" suggeriert ja, dass es genauso gut umgekehrt hätte sein können)

Warum nicht Tupel verwenden, wenn die Information unverändert bleibt, und Listen nur dann, wenn sie im Laufe des Algorithmus abgeändert werden muss? Falls Werte unterschiedlichen Bedeutung haben und trotzdem abgeändert werden müssen (theoretischer Fall), dann könnte ich die Konvention sowieso nicht befolgen und wäre gezwungen eine Liste zu nehmen.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Es gibt da noch eine weitere Konvention: Listen sollten homogen sein.

Wie funktionale Programmierung wunderbar zeigt muss man übrigens niemals irgendwas abändern.
BlackJack

@Goswin: Falls Werte unterschiedliche Bedeutungen haben und geändert werden müssen, sollte man gar keine Liste nehmen, denn dann hätte man ein Programm mit magischen Indexwerten was schwerer zu verstehen ist. Auch bei unveränderlichen Elementen würde man auch besser zu `collections.namedtuple()` greifen wenn man nicht magische Indexwerte haben möchte.

Umkehren kann man das auch deswegen schlecht weil es beispielsweise Sprachmittel wie „list comprehension“ (LC) nur für Listen gibt und Listenverarbeitung, nun ja, nun mal mit Listen gemacht wird. Und Listen sollten gleichartige Elemente, mit gleicher Bedeutung enthalten, denn nur dann kann man da mit einfachem, verständlichem Code und den Werkzeugen wie LCs oder den `itertools`-Funktionen drauf operieren. Da Tupel nicht veränderbar sind, kann man sie nur ineffizient mit dynamischer Länge erstellen, also entweder über den Umweg einer Liste, oder in dem man Tupel zu neuen Tupeln zusammen setzt, und dabei dann aber jedes mal ein neues Tupel erstellt und wahrscheinlich die beiden alten Teile weg wirft.
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

BlackJack hat geschrieben:Da Tupel nicht veränderbar sind, kann man sie nur ineffizient mit dynamischer Länge erstellen, also entweder über den Umweg einer Liste, oder in dem man Tupel zu neuen Tupeln zusammen setzt, und dabei dann aber jedes mal ein neues Tupel erstellt und wahrscheinlich die beiden alten Teile weg wirft.
Damit rennst du ja offene Türen ein, denn ich benutze für Sequenzen, die verändert werden müssen, (wie erwähnt) sowieso Listen. Meine Frage war ja eine andere: warum sollte ich für unveränderbare Sequenzen mit Einträgen gleicher Art keine Tupel benutzen? Zum Beispiel arbeite ich manchmal mit Tupeln an Stelle von integers: ()==pfad(1), (2,)==pfad(2), (3,3,2,)==pfad(18), (5,3,2,2,2,)==pfad(120).
BlackJack

@Goswin: Weil man sich dann beim lesen fragt welche besondere Bedeutung die einzelnen Indexpositionen haben, denn per Konvention müssten sie die ja haben. Das ist verwirrend.

Und wie sieht `pfad()` aus? Wie kommen die Tupel mit dynamischer Länge in der Funktion zustande?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Man sollte vielleicht auch mal den größeren Kontext betrachten, Tupel sind schliesslich keine reine Python Erfindung. In der Mathematik ist die Länge eines Tupels quasi ein Teil des Typs und in anderen Programmiersprachen wie z.B. Haskell ist dies ebenfalls der Fall.

In Python ist man zwar daran nicht gebunden aber man sollte sich schon gut überlegen wann man sich davon trennt.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich finde es jetzt auch nicht so super-dramatisch, Tupel zu benutzen, um Pfade abzubilden.

Aber was BlackJack andeutet, stimmt schon: Der Pfad kommt ja vermutlich sowieso durch schrittweises Hinzufügen der Knotenpunkte zustande. Dies macht man sinnvollerweise mit Listen. Warum dann nicht bei einer Liste bleiben?
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

BlackJack hat geschrieben:@Goswin:
Wie sieht `pfad()` aus? Wie kommen die Tupel mit dynamischer Länge in der Funktion zustande?
Na ja:
Die Primzahlzerlegung einer Zahl wird einmal ausgerechnet und verändert sich dann nie nie wieder :) !
Über die Primzahlzerlegung kann ich iterieren, aber über den Integer kann ich nicht iterieren.
BlackJack

@Goswin: Naja aber um das Tupel zu erstellen müsste es veränderbar sein. Die Funktion wird also sehr wahrscheinlich eine Liste verwenden die am Ende dann in ein Tupel umkopiert wird. Warum?
Antworten