A list comprehension executes immediately and returns a list, which is an iterable object.
A generator expression is an iterator object. It does almost the same as list comprehension but does it lazily.
Iterable is an object, which one can iterate over. It generates an Iterator when passed to iter()
method. Iterator is an object, which is used to iterate over an iterable object using __next__()
method. Iterators have __next__()
method, which returns the next item of the object.
Note that every iterator is also an iterable, but not every iterable is an iterator.
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), end=' ')
print(next(iterator_obj), end=' ')
print(next(iterator_obj), end=' ')
print(next(iterator_obj), end=' ')
print(next(iterator_obj))
2 3 5 7
--------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-2-4857e73348c9> in <module> 5 print(next(iterator_obj), end=' ') 6 print(next(iterator_obj), end=' ') ----> 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
Let's see the differences between list comprehension and generator expression again:
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 'generator' object is not subscriptable, and we can iterate over it only once. So in embedded loops, we can not use two generator expression:
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
# we have to generate g2 at every cicle
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
Let us throw two dice, a red and a blue one, and let s denotes the sum. What is the relative frequency (relative frequency of a conditional event) of 1 on the red die if s is given? What is the relative frequency of any other number on the red die if s is given? For which value of s will be this frequency close to 1/6?
from random import randint
two = [red, _] = [randint(1,6), randint(1,6)]
two, red
([6, 2], 6)
two = [randint(1,6), randint(1,6)]
red = two[0]
two, red
([5, 3], 5)
s = sum(two)
two, s, red
([5, 3], 8, 5)
sum2 = 5 # 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.2709497206703911 0.16666666666666666
Let us throw two dice, a red and a blue one, and let s denotes the sum. What is the probability that the number r is on the red die if s is given? For which value of s will be this frequency equal to 1/6?
sum2 = 7 # sum of the two numbers
die = 4 # 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
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?"
There are three possible answers:
Write a program, which simulate 1000 times all these three playing strategies. The program
Finaly the program writes out the three relative frequencies of winning the car in the next form:
Keep the decision 0.457
Change the decision 0.568
All the same 0.347
About this task:
There are a lot of information on this problem on the Internet, but first try to understand and answer the question and write the program before reading them.