A listaértelmezés azonnal kiértékelődik és egy listát ad vissza, ami bejárható (iterálható, iterable) objektum.
A generátorkifejezés egy bejáró (iterátor, iterator), ami – mint minden bejáró – egyúttal bejárható.
A bejárható objektum olyan, amelynek elemein végigjárhatunk (pl. lista). Ha átadjuk az iter()
metódusnak, egy bejáró keletkezik. A bejáró (iterator) olyan objektum, mely egy bejárható objektumon végigfut a __next__()
metódussal.
for num in [2, 3, 5, 7]:
print(num, end=' ')
2 3 5 7
numbs = [2, 3, 5, 7]
iterator_obj = iter(numbs)
print(next(iterator_obj))
print(next(iterator_obj))
print(next(iterator_obj))
print(next(iterator_obj))
print(next(iterator_obj))
2 3 5 7
--------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-2-4f926c4bb17b> in <module> 5 print(next(iterator_obj)) 6 print(next(iterator_obj)) ----> 7 print(next(iterator_obj)) StopIteration:
iterator_obj = iter(numbs)
try:
print(next(iterator_obj), end=' ')
print(next(iterator_obj), end=' ')
print(next(iterator_obj), end=' ')
print(next(iterator_obj), end=' ')
print(next(iterator_obj)) #StopIteration error
except:
pass
2 3 5 7
Lássuk még egyszer a különbségeket:
lst = [n for n in range(10000)]
gen = (n for n in range(10000))
print(type(lst), type(gen))
<class 'list'> <class 'generator'>
from sys import getsizeof
print(getsizeof(lst), getsizeof(gen))
87616 112
for i in lst:
if i == 100:
print(i)
100
for i in gen:
if i == 100:
print(i)
100
lst[100]
100
gen[100] # we can iterate through the items
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-10-36903d332c5f> in <module> ----> 1 gen[100] # we can iterate through the items TypeError: 'generator' object is not subscriptable
A generátor nem indexelhető, és csak egyszer futhatunk végig az elemein, így – ellentétben a listával –, egymásba ágyazott ciklusoknál nem lehet mindkét bejárható objektum generátor kifejezés:
g1=(i for i in range(3))
g2=(j for j in range(3))
for i in g1:
for j in g2:
print(i,j)
0 0 0 1 0 2
# minden ciklusban újra kell generálni g2-t
g1=(i for i in range(3))
for i in g1:
g2=(j for j in range(3))
for j in g2:
print(i,j)
0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 1 2 2
Eldobunk egy piros és egy kék kockát. A rajtuk lévő számok összege legyen s. Mi a relatív gyakorisága annak, hogy a piros kockán 1-es van, feltéve, hogy a két kockán lévő számok összege s egy előre megadott, rögzített szám? Mi a relatív gyakorisága bármely másik számnak, feltéve, hogy a két kockán lévő számok összege s? Mely s összeg esetén lesz egy szám ezen feltétel melletti relatív gyakorisága közel az 1/6-hoz?
from random import randint
two = [red, _] = [randint(1,6), randint(1,6)]
two, red
([2, 6], 2)
two = [randint(1,6), randint(1,6)]
red = two[0]
two, red
([2, 5], 2)
s = sum(two)
two, s, red
([2, 5], 7, 2)
sum2 = 7 # sum of the two numbers (2..12)
die = 1 # the number on the die we are waiting for (1..6)
count = 0 # counter of the cases with sum == <sum2>
count_red = 0 # counter when the red die == <die>
for i in range(10000):
two = [randint(1,6), randint(1,6)]
red = two[0]
s = sum(two)
if s == sum2:
count += 1
if red == die:
count_red += 1
print(count_red/count, 1/6)
0.17461263408820024 0.16666666666666666
Eldobunk egy piros és egy kék kockát. A rajtuk lévő számok összege legyen s. Mi a valószínűsége, hogy a piros kockán lévő szám épp r, feltéve hogy az összeg az előre megadott s szám? Mely s értékekre lesz e valószínűség 1/6?
sum2 = 7 # sum of the two numbers
die = 2 # the number on the die we are waiting for
count = 0 # counter of the cases with sum == <sum2>
count_red = 0 # counter when the red die == <die>
for red in range(1, 7):
for blue in range(1, 7):
s = red + blue
if s == sum2:
count += 1
if red == die:
count_red += 1
print(count_red/count, 1/6)
0.16666666666666666 0.16666666666666666
A Monty Hall-paradoxon egy valószínűségi paradoxon, ami az Amerikai Egyesült Államokban futott Let's Make a Deal (Kössünk üzletet) című televíziós vetélkedő utolsó feladatán alapul, nevét a vetélkedő műsorvezetőjéről, Monty Hallról kapta. (A műsor magyar változatának címe Zsákbamacska volt, és Rózsa György vezette.)
A műsor végén a játékosnak mutatnak három csukott ajtót, amelyek közül kettő mögött egy-egy kecske van, a harmadik mögött viszont egy vadonatúj autó. A játékos nyereménye az, ami az általa kiválasztott ajtó mögött van. Azonban a választás meg van egy kicsit bonyolítva. Először a játékos csak rámutat az egyik ajtóra, de mielőtt valóban kinyitná, a műsorvezető a másik két ajtó közül kinyit egyet, amelyik mögött nem az autó van (a játékvezető tudja, melyik ajtó mögött mi van), majd megkérdezi a játékost, hogy akar-e módosítani a választásán. A játékos ezután vagy változtat, vagy nem, végül kinyílik az így kiválasztott ajtó, mögötte a nyereménnyel. A paradoxon nagy kérdése az, hogy érdemes-e változtatni, illetve hogy számít-e ez egyáltalán.
From Wikipedia: "The Monty Hall problem is a brain teaser, in the form of a probability puzzle, loosely based on the American television game show Let's Make a Deal and named after its original host, Monty Hall. The problem was originally posed (and solved) in a letter by Steve Selvin to the American Statistician in 1975. It became famous as a question from a reader's letter quoted in Marilyn vos Savant's "Ask Marilyn" column in Parade magazine in 1990:
Suppose you're on a game show, and you're given the choice of three doors: Behind one door is a car; behind the others, goats. You pick a door, say No. 1, and the host, who knows what's behind the doors, opens another door, say No. 3, which has a goat. He then says to you, "Do you want to pick door No. 2?" Is it to your advantage to switch your choice?"
Három játéktaktika lehetséges e kérdés után:
Írjunk programot, mely szimulálja e három játékstratégiát, mindegyiket 1000-szer. A program
eredményül írjuk ki a játékos nyerésének relatív gyakoriságát a három esetben a következő táblázat mintájára:
Marad a kiválasztott ajtó 0.245
Másik ajtót választ 0.567
Mindegy 0.671
A feladat célja: a relatív gyakoriság szimuláción keresztül való megtapasztalása és a feltételes valószínűség fogalmának előkészítése egy paradoxonnak tűnő problémán keresztül.
A feladat a példatárban 2.20 sorszámmal szerepel.