random.choices возвращает массив [True]
или [False]
:
$ python
Python 3.10.0 (default, Oct 16 2021, 12:17:56) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
@>>> import random
@>>> random.choices([True, False], weights=[0.9, 0.1])
[True]
А массив не бывает равным True
:
@>>> [True] == True
False
@>>> [False] == True
False
Все проверки проваливаются, код не работает как ожидается.
Можно взять из массива первый элемент ([0]
в конце строки):
b = random.choices([True, False], weights=[0.9, 0.1])[0]
Можно взять из массива первый элемент c помощью tuple destructuring assignment (,
в начале строки):
b, = random.choices([True, False], weights=[0.9, 0.1])
Вам нужна истина с вероятностью 0.9, иначе ложь. random.random возвращает равномерно распределённые вещественные числа на полуинтервале [0, 1). Отсюда классическое решение задачи:
b = random.random() < 0.9
Совершенно случайно вероятность выражена рациональной дробью. Для дробей возможен трюк с random.randrange. Знаменатель дроби в скобках, числитель в правой части неравенства:
b = random.randrange(10) < 9 # 9/10 probability
P.S. Вы меняете список по которому в данный момент происходит цикл. Это не хорошо, но в данном случае ничего ужасного не происходит - код будет работать так как вы ожидаете. Будьте осторожны:
import random
zoo = [1, 2, 3, 4, 5]
for item in zoo:
if random.random() < 0.9:
zoo.append(item)
print(len(zoo), ':', *zoo)
P.P.S. Или так:
import random
zoo = [1, 2, 3, 4, 5]
zoo += (i for i in zoo if random.random() < 0.9)
print(len(zoo), ':', *zoo)
P.P.P.S. Я наконец понял что было нужно:
import random
zoo = [1, 2, 3, 4, 5]
zoo += [i for i in zoo if random.random() < 0.9]
print(len(zoo), ':', *zoo)
Надеюсь, вы понимаете чем последний вариант отличается от предпоследнего.