python random.choices() почему при выводе случайного булевого значения не добавляется значение в список

Рейтинг: 0Ответов: 2Опубликовано: 31.03.2023

Почему метод random.choices() не добавляет новые значения в список.

import random

zoo = [1,2,3,4,5]

for item in zoo:
    b = random.choices([True, False], weights=[0.9, 0.1])
    if b == True:
        zoo.append(item)

print(zoo)

Ответы

▲ 1Принят

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)

Надеюсь, вы понимаете чем последний вариант отличается от предпоследнего.

▲ 0
import random

zoo = [1,2,3,4,5]
new_zoo = []
for items in (zoo):
    a = random.choices([1, 0], weights=[0.9, 0.1])
    b = int(''.join(map(str,a)))
    c = bool(b)

    if c == True:
        new_zoo.append(items)

zoo += new_zoo

print(zoo)
print(new_zoo)
print(c, type(c))

В итоге нашел ответ, корректно работает теперь цикл. Прошу знающих людей указать как с точки зрения правильности написания кода указать как его написать локаничней, правильней и красивей =) Всем спасибо!