Iterieren bis 49*48*47*46*45*44

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
murphy
User
Beiträge: 60
Registriert: Samstag 30. Oktober 2004, 01:34
Wohnort: Berlin
Kontaktdaten:

Iterieren bis 49*48*47*46*45*44

Beitragvon murphy » Montag 23. Oktober 2006, 09:40

hi!

Python kennt ja große zahlen:

Code: Alles auswählen

>>> 49*48*47*46*45*44
10068347520L


nun wollte ich gerne so oft eine berechnung ausführen; for i in range(...) schien mir das richtige mittel:

Code: Alles auswählen

>>> for i in range(49*48*47*46*45*44):
...   pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: range() result has too many items
geht also nicht - klar, range erzeugt ja eine liste, und die wäre zu groß. also nehme ich xrange:

Code: Alles auswählen

>>> for i in xrange(49*48*47*46*45*44):
...   pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: long int too large to convert to int
Python mag mich nicht ^^

wie krieg ich das hin? ich weiß, dass die schleife lange laufen wird, aber es sollte doch möglich sein, das ohne while zu machen.

ps: es geht natürlich um eine dieser "6 aus 49"-matheaufgaben aus der uni.
BlackJack

Beitragvon BlackJack » Montag 23. Oktober 2006, 09:58

Da wirst Du wohl nicht um ``while`` herumkommen. Du kannst die Schleife aber in einer Funktion verstecken:

Code: Alles auswählen

def xxrange(n):
    i = 0
    while i < n:
        yield i
        i += 1


Dir ist schon klar das man diese Uni-Lotto-Aufgaben auch ohne "brute-force" Programme lösen kann? Das ist eigentlich der Sinn dieser Aufgaben. :-)

edit: Wenn eine Iteration eine Millisekunde dauert, dann wartest Du auch nur 116 Tage auf das Ergebnis. :-D
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Montag 23. Oktober 2006, 11:47

Milan hat auch schon mal xrange in Python implementiert, so dass es auch mit Longs auskommt. Ich finde es momentan zwar nicht (ihh, Internet-Stehplatz mit Sitekiosk) aber du solltest mit dem Stichwort xlrange etwas brauchbares finden können.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Beitragvon Joghurt » Donnerstag 26. Oktober 2006, 21:19

murphy, dir ist bewusst, dass selbst wenn Python 10000 Schleifendurchläufe pro Sekunde schafft, es über 11 Stunden dauert, bis es durch ist?
Benutzeravatar
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Beitragvon mitsuhiko » Samstag 28. Oktober 2006, 10:23

Du könntest count() dafür verwenden:

Code: Alles auswählen

from itertools import count
max = 49*48*47*46*45*44
for i in count():
 if i == max:
  break
 print "foo"

Aber für was brauchst du so große Zahlen? Oo
TUFKAB – the user formerly known as blackbird
BlackJack

Beitragvon BlackJack » Samstag 28. Oktober 2006, 11:20

Bis Python 2.4 kannst Du `count()` nicht benutzen:

Code: Alles auswählen

In [11]: a = itertools.count(sys.maxint)

In [12]: a.next()
Out[12]: 2147483647

In [13]: a.next()
Out[13]: -2147483648


In Python 2.5 ist diese nette Überraschung korrigiert worden. :-)
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Samstag 28. Oktober 2006, 14:34

Stimmt nicht:

Code: Alles auswählen

>>> x = itertools.count(-1)
>>> x.next()
4294967295L
>>> x.next()
0
>>> x.next()
1


Das ist ein Bug in 2.5. In 2.5.1 wird count() wieder wie in 2.4 korrekt mit negativen counts funktionieren und bei sys.maxint wrappen.

Dass count() nur den Bereich von native ints abdeckt, ist laut Raymond so gewollt.
BlackJack

Beitragvon BlackJack » Samstag 28. Oktober 2006, 15:43

Was ist denn das für ein Schwachsinn. Das läuft total den Erwartungen nach der `int()`/`long()` Vereinheitlichung entgegen und ist ziemlich low-level und plattformabhängig. Irgendwie unpythonisch.

Wo hat Hettinger das denn gesagt und eventuell begründet? Gibt's 'ne Referenz?
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Samstag 28. Oktober 2006, 17:08

Ich habe das verwechselt. Er hat es nicht als gewollt bezeichnet, sondern sagte in einem feature request:
It's not a bug -- it is the documented behavior.
The simple work-around is to roll your own generators:
[...]
Will look at possibly enhancing this for Py2.5.


Er ist aber nicht dazugekommen :)

Wer ist online?

Mitglieder in diesem Forum: redone