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

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

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
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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 (former) Modvoice
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

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

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

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

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

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

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 :)
Antworten