mal grundsaetzlich: python vs. php...etc

Alles, was nicht direkt mit Python-Problemen zu tun hat. Dies ist auch der perfekte Platz für Jobangebote.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

List Comprehensions sind schon länger drin, Generators sein 2.2 per future und in 2.3 per default. Generator Expressions sind ab 2.4 dabei, aber was sind sie denn? Viele Leute haben schon erzählt wie toll sie sind,aber ich weis nichtmal was sie sind. Genausowenig sehe ich was an den Python 2.3 sets so toll ist, das ist halt eine Art List mit add() und remove() wo es keine doppelten Werte gibt, oder?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi Leonidas!

Das gibt's doch erst in 2.4 hat sich nur auf Generator Expressions bezogen. Aber danke für die Nachhilfe in Python-Historie :D

Gruß, mawe
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Leonidas hat geschrieben:List Comprehensions sind schon länger drin, Generators sein 2.2 per future und in 2.3 per default. Generator Expressions sind ab 2.4 dabei, aber was sind sie denn? Viele Leute haben schon erzählt wie toll sie sind,aber ich weis nichtmal was sie sind.
Hi. Im Prinzip sind sie List comprehensions, aber jedes Element wird halt erst erzeugt, wenn es gebraucht wird. Schau dir mal den Code hier an:

Code: Alles auswählen

a=lambda num=10:[x**2 for x in xrange(num) if x%2]
#ist dasselbe wie:
def a(num=10):
    erg=[]
    for i in xrange(num):
        if i%2:
            erg.append(i**2)
    return erg

#kann man auch als generator schreiben:
def b(num=10):
    for i in xrange(num):
        if i%2:
            yield i**2
#oder noch besser als
b=lambda num=10: (x**2 for x in xrange(num) if x%2)
a liefert eine Liste, b ein Generator, also ist b speicherfreundlicher und trotzdem genauso kompakt. Man kann aber sagen a(x)==list(b(x)) .
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

mawe hat geschrieben:Das gibt's doch erst in 2.4 hat sich nur auf Generator Expressions bezogen. Aber danke für die Nachhilfe in Python-Historie :D
Hups, sorry, das kommt davon wenn man nicht schaut wer was geschrieben hat.

@Milan: also ist bei den Generator Expressions in Lambdaform nur der Unterschied das es runde statt eckigen Klammern gibt und es dadurch von einer List Comprehension zu einer Generator Expression wird?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

noch was zu Generatorexpressions.
Generatorexpressions kannst Du überall verwenden, wo du sonst erst eine Liste erzeugen würdest.

Code: Alles auswählen

a = [x*x for x in xrange(1,101)]
print a # gibt eine Liste aus mit den Quadraten der Zahlen 1 bis 100
a = (x*x for x in xrange(1,101))
print a # <generator object at 0x...>[/b]
a = dict(enumerate(x*x for x in xrange(1,101)))
print a
Das ganze bringt einen neuen Schub in die funktionale Programmierung in Python.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hups, jetzt wolle ich das mit Python 2.3 testen, oh wunder geht nicht.
Gibt es nicht irgendwo eine from __future__ import Funktion zum Nutzen von Generator Expressions in Python 2.3?
Wofür gibt es eigentlich die __future__ imports? Das Zeug dort ist doch sowieso wieder im nächsten größeren Release per default drin.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
murphy
User
Beiträge: 60
Registriert: Samstag 30. Oktober 2004, 01:34
Wohnort: Berlin
Kontaktdaten:

@leonidas:
print ist in Ruby eine methode, ohne dass man es merkt. dazu muss man allerdings das mit dem toplevel-objekt verstehen, das kann ich jetzt nicht noch ausführen (ist ja auch kein Ruby-forum ;))

also __len__ mag ich nach wie vor nicht, auch mit historischen gründen :) lassen wir das.

@Dookie: newsytle und oldstyle-klassen, die ich unterschiedlich benutzen muss? urks...klingt kompliziert ;)
readonly-attribute und virtuelle methoden gehen in Ruby auch, mit attr_reader und method_missing.

@milan: ja du darfst klammern benutzen, musst du ja manchmal. seit Haskell benutze ich sie eigentlich nie, solange es sich vermeiden lässt.
Das ist ein Spezialfall
schade. spezialfall bedeutet für mich, dass ich ihn speziell behandeln muss, das schränkt meine freiheit ein und steigert den lern- und schreibaufwand.
aber ohne spezialfälle kommt wohl keine sprache aus.
in Ruby gibt methods einfach ein array mit methodennamen zurück.
Da macht es aber wirklich Sinn, denn del hat mehr als eine Bedeutung. Du kannst damit sowohl Referenzen auf Variablen vernichten als auch einzelne Elemente in Listen oder Dictionarys löschen.
del hat verschiedene bedeutungen, und deshalb ist es keine methode? :kopfkratz: naja, da kommen wir wohl nicht weiter.

@mawe: list comprehensions in Ruby? die antwort sind codeblöcke:

Code: Alles auswählen

p (1..16).select { |x| x % 2 == 0 }  #-> [2, 4, 6, 8, 10, 12, 14, 16]
p ('A'..'E').map { |x| x * 3 }  #-> ["AAA", "BBB", "CCC", "DDD", "EEE"]
beim zweiten hab ich die Python-entsprechung noch gar nicht gefunden...

---

ich will hier niemanden zu Ruby konvertieren oder Python schlecht machen. mir persönlich kommen nur viele dinge seltsam vor, und ich finde Ruby's antworten auf viele fragen einfach besser und logischer.
beide sprachen sind einerseits viel weiter entwickelt als diese öden mainstreamsprachen, andererseits auch weit davon entfernt, perfekt zu sein. beide haben voneinander gelernt, und diskussionen über die unterschiede führen hoffentlich zu noch besseren sprachen.
schade nur, dass sich einige konzepte so radikal auschließen: whitespace-anarchie vs. indent-pflicht, implizite methoden vs. explizites self, optionale vs. leere klammern...
Ruby mit Python zu mischen scheint mir unmöglich.

wer noch ein paar MB frei hat, sollte sich Ruby trotzdem installieren, und wenn man es nur für einzeiler einsetzt (statt Perl ;))
Python wird jedenfalls auf meinem system bleiben, leider weiß ich im moment nicht, was ich drin programmieren sollte...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

murphy hat geschrieben:

Code: Alles auswählen

p (1..16).select { |x| x % 2 == 0 }  #-> [2, 4, 6, 8, 10, 12, 14, 16]
p ('A'..'E').map { |x| x * 3 }  #-> ["AAA", "BBB", "CCC", "DDD", "EEE"]
beim zweiten hab ich die Python-entsprechung noch gar nicht gefunden...
Kein Problem da helfe ich dir aus, List Comprehensions verstehe sogar ich:

Code: Alles auswählen

[i * 3 for i in ('A', 'B', 'C', 'D', 'E')]
['AAA', 'BBB', 'CCC', 'DDD', 'EEE']
Edit: mir ist grad aufgefallen das das auch einfacher geht:

Code: Alles auswählen

[i * 3 for i in 'ABCDE']
['AAA', 'BBB', 'CCC', 'DDD', 'EEE']
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Tja, das mit den Newstyle Klassen ist noch serh neu in Python und muss sich erst noch vollständig etablieren. Solange gibt es eine Übergangsphase mit beiden Varianten. Newstyle mäßig kann Python dann aber doch schon einges mehr an OOP. Das ist mir jetzt aber zu viel zu schreiben, das überlass ich unserem Dookie :D .
murphy hat geschrieben:
Das ist ein Spezialfall
schade. spezialfall bedeutet für mich, dass ich ihn speziell behandeln muss, das schränkt meine freiheit ein und steigert den lern- und schreibaufwand.
aber ohne spezialfälle kommt wohl keine sprache aus.
in Ruby gibt methods einfach ein array mit methodennamen zurück.
Solange es nur der Spezialfall zur ausgabe ist :wink: ...
Da macht es aber wirklich Sinn, denn del hat mehr als eine Bedeutung. Du kannst damit sowohl Referenzen auf Variablen vernichten als auch einzelne Elemente in Listen oder Dictionarys löschen.
del hat verschiedene bedeutungen, und deshalb ist es keine methode? :kopfkratz: naja, da kommen wir wohl nicht weiter.

Code: Alles auswählen

a=[1,2,3,4,5]
print a
del a[1] #lösche die 2
print a
del a[1:3] #lösche die 3 und 4
print a
del a
print a #NameError
Ließe sich bestimmt auch als Methode machen, aber warum? del geht ja nicht nur für Objekte, die Container sind.
@mawe: list comprehensions in Ruby? die antwort sind codeblöcke:

Code: Alles auswählen

p (1..16).select { |x| x % 2 == 0 }  #-> [2, 4, 6, 8, 10, 12, 14, 16]
p ('A'..'E').map { |x| x * 3 }  #-> ["AAA", "BBB", "CCC", "DDD", "EEE"]
beim zweiten hab ich die Python-entsprechung noch gar nicht gefunden...
Naja, das geht dann auch mit List Comprehensions... früher mit map, aber das ist dadurch überfallig geworden.

Code: Alles auswählen

[x for x in xrange(1,17) if x%2==0]
[x*3 for x in "ABCDE"]
wer noch ein paar MB frei hat, sollte sich Ruby trotzdem installieren, und wenn man es nur für einzeiler einsetzt (statt Perl ;))
Python wird jedenfalls auf meinem system bleiben, leider weiß ich im moment nicht, was ich drin programmieren sollte...
Genauso geht es mir, wenn ich mir ruby installieren wollte. Ich finde einige Konzepte genial, aber der Großteil missfällt mir leider. Ich würde automatisch wieder in mein Pythonstil zurückfallen. Aber über Sprachen zu diskutieren macht mir Spaß, man lernt eine Menge dabei und kann sich Ideen holen. Ich bin sicher, dass beide in Zukunft auch noch viel voneinander lernen werden, aber jede Sprache ihren eigenen Weg geht... so ists ja immer, wenn Sprachen von anderen "abgucken". :wink: :lol: .
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!
murphy hat geschrieben: list comprehensions in Ruby? die antwort sind codeblöcke:
Ich weiß, hast Du mir ja schon im Ruby-Forum gezeigt :D. map gibt's in Python auch. Hab ich anfangs auch verwendet (weil ich's von Perl gewöhnt war). Mittlerweile nehme ich nur noch LC. Findest Du die nicht auch ... wie soll ich sagen ... intuitiver (na gut, das schreibt man sicher anders :D. Ich hoffe Du weißt was ich meine).
murphy hat geschrieben: beim zweiten hab ich die Python-entsprechung noch gar nicht gefunden
Brauchst nicht lange suchen. Die Antwort ist eine ... tadaa! ... List Comprehension :D

Gruß, mawe
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dier fand ich ganz nett zum Verstehen von LCs: http://www.secnetix.de/~olli/Python/lis ... sions.hawk
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hi

tolle Diskussion (die im Ruby-Forum ist auch nicht schlecht) ;-). Bei meinem ersten Antwortversuch zur eigentlichen Frage ist bei uns leider das Netz zusammengebrochen :? , aber die Diskussion hat sich ja doll entwickelt.

Ich verstehe bloß den Trubel um Pythons spezielle Klassenmethoden (à la __len__ ) nicht: __len__ zu definieren ist doch u. U. semantisch notwendig in einer Klasse. Das dürfte doch allen klar sein (scheint ja auch allen klar zu sein). Wo ist denn das Problem, wenn man zum Aufruf mehrere Optionen hat? Vermisst jemand syntaktische Eindeutigkeit? Warum? Klärt mich doch bitte mal auf.

Im Übrigen habe ich - durch diese Diskussion angeregt - entdeckt, daß auf meiner Obstkiste Ruby schon vorinstalliert war. Kurzes Reinschnuppern war sehr interessant, aber mir geht es wie Dir, murphy, ich bleibe lieber, bei dem was ich kenne und schätze.

Gruß und schönes Wochenende,
Christian
Malte aus dem Ruby-Forum

CM hat geschrieben:__len__ zu definieren ist doch u. U. semantisch notwendig in einer Klasse. Das dürfte doch allen klar sein (scheint ja auch allen klar zu sein). Wo ist denn das Problem, wenn man zum Aufruf mehrere Optionen hat? Vermisst jemand syntaktische Eindeutigkeit?
Da ich Python kaum kenne, kann ich hier natürlich schlecht mitreden, trotzdem versuch ich es mal. Wenn ich in Python programmieren müsste und len(str) statt str.length schreiben müsste, wäre das erste Gegenargument natürlich, dass es nicht so wie in Ruby ist ;-). An zweiter Stelle geht es hier um das "OO-feeling" (gibt es so was?), da der Ruby-Code mir zeigt, das length eine Methode von String ist, während der Python-Code vor mit versteckt, dass __len__ eine Methode von String ist.

Grüße
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!

Ruby ist ja u.a. mit dem Ziel entwickelt worden, "objektorientierter" zu sein als Python. Das zeigt sich auch in der Syntax. Welche man bevorzugt, ist meiner Meinung nach Geschmackssache. Es würde mich nicht wirklich stören, wenn man in Python auch "hello".length() schreiben könnte, es ärgert mich allerdings auch nicht sonderlich daß man es nicht tut :wink:. (Um ehlich zu sein hab ich mich noch nicht dafür interessiert, wie Python z.B. len intern behandelt).
Es gibt allerdings etwas, das mich bei Python nervt: join :evil:

Code: Alles auswählen

x = "h.e.l.l.o".split(".")   # -> ['h','e','l','l','o']
".".join(x)   # warum nicht x.join(".")
Gibt's da eine Erklärung?

Gruß, mawe
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

HI. Ja mawe, die gibts: ich fänd es nämlich sehr dumm, wenn eine Liste eine Methode beherrschen würde, bei der ein String rauskommt, also eigentlich eine Stringoperation. Da seh ich das schon sinnvoller so zu schreiben: verbinde mit "." die Liste x. Da join eine Methode von str ist, weiß ich auch, dass ein str rauskommt :D .
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!
Milan hat geschrieben: ... ich fänd es nämlich sehr dumm, wenn eine Liste eine Methode beherrschen würde, bei der ein String rauskommt ...
Versteh' ich nicht. split ist ja auch ein Stringmethode und es entsteht eine Liste. Ist es dadurch eine Listenmethode?
Milan hat geschrieben: ... verbinde mit "." die Liste x ...
Ich fände es so einleuchtender: Verbinde die Elemente der Liste x mit einem "." :wink: Sieht so aus als wäre das wieder mal Geschmackssache :D

Gruß, mawe
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

mawe hat geschrieben:Versteh' ich nicht. split ist ja auch ein Stringmethode und es entsteht eine Liste. Ist es dadurch eine Listenmethode?
Hi. Gutes Argument... dann lags halt an der Faulheit der Programmierer, die den Kompromiss in Kauf nehmen um nicht mehr schreiben zu müssen, bzw einfach am praktischem Nutzen. Denn dann hätte man join für alle iterables definieren müssen und das wäre dumm gewesen wenn du mal selber eine solchen schreibst, oder einfach nur Generatorfunktionen durchlaufen lässt. Es würde sich auch negativ auf die Performance auswirken :wink: .
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ich seh das len() Problem auch nicht wirklich, wenn man jetzt unbedingt so OO wie möglich programmieren will, dann kann man ruhig auch __len__() aufrufen. Wenn man es noch weiter treiben will kann man auch die Operatoren auslassen und direkt mit __mul__ und co arbeiten. :twisted:
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
oenone
User
Beiträge: 75
Registriert: Mittwoch 27. August 2003, 14:39
Wohnort: 49°17'28N, 8°15'57E
Kontaktdaten:

du kannst join() ja nicht nur auf Listen, sondern auch auf Tupel, Dictionaries und allen anderen sequenzierbaren objekten benutzen, sofern sie strings zurueckliefern.

auf bald
oenone
if you don't remember something, it never happened.
if you aren't remembered, you never existed.
i don't quite understand what love is like... but if there was someone who liked me, i'd be happy.
murphy
User
Beiträge: 60
Registriert: Samstag 30. Oktober 2004, 01:34
Wohnort: Berlin
Kontaktdaten:

mawe hat geschrieben:Mittlerweile nehme ich nur noch LC. Findest Du die nicht auch ... wie soll ich sagen ... intuitiver
ich kenne sie von Haskell. aber anstatt for und if eine zweite bedeutung zu geben, hat man in Ruby eben ein allgemeineres konzept benutzt.
in codeblöcke kann man auch mal größere mengen code hineinschreiben.

Code: Alles auswählen

if x not in noprimes
ist natürlich eine schöne fomulierung, die in Ruby zugunsten der OO nicht vorhanden ist. da wäre es

Code: Alles auswählen

not noprimes.include?(x)
die list comprehensions gibt es wohl auch nicht, weil es ein neues konzept für etwas wäre, was man auch mit codeblöcken lösen kann.
es gibt dinge, die man mit LC nicht lösen kann, aber offenbar auch andere, die sich damit nur schwer lösen lassen:

Code: Alles auswählen

#noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
noprimes = []
(2..8).each { |i| (i*2..50).step(i) { |x| noprimes << x } }
ich habe mal ein wenig herumexperimentiert, und ein simples LC-interface für Ruby geschrieben:

Code: Alles auswählen

class LC
	attr :values
	def initialize
		@values = []
	end
	
	def add x
		@values << x if x
	end
	alias :add= add
end

def list &block
	lc = LC.new
	lc.instance_eval &block
	lc.values
end

#noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
noprimes = list { (2..8).each { |i| (i*2..50).step(i) { |j| add j } } }
p noprimes.uniq.sort
p (2..50).to_a - noprimes
es ist ein wenig länger als die PYthon-variante, aber brauchbar. das ärgerliche sind natürlich die vielen { klammern }.
könnte jemand bitte codeblöcke in Python simulieren ;)
Antworten