Как в Python работать со случайными числами

Содержание:

В рамках полезных советов по изучению Python рассмотрим возможности языка при работе со случайными числами и данными.

Случайные числа

Случайные числа не случайны, как бы парадоксально это ни прозвучало. Точнее, те последовательности чисел, которые получают программным методом в языках программирования, истинно случайными не являются. Они называются псевдослучайными, поскольку привязаны, как правило, к системному времени, вычисляются с помощью алгоритмов, а их последовательности цикличны, т. е. повторяются с каким-либо периодом и подчиняются определенному закону распределения, например нормальному или равномерному.

Примеры истинно случайных чисел встречаются в природе при регистрации шумов: радиации, электрического тока, космического излучения, атмосферных колебаний и т. д. Но использование таких чисел нецелесообразно ввиду дороговизны их получения и обработки, больших временных затрат и невозможности воспроизвести полученную ранее последовательность. На практике используют либо псевдослучайные числа, либо числа, порожденные физическим источником, от которых в дальнейшем воспроизводится псевдослучайная последовательность.

В статье условимся псевдослучайные числа называть случайными.

Случайные числа находят свое применение в:

  • системах математического моделирования и симуляции физических процессов;
  • криптографии;
  • теории вероятностей;
  • теории игр;
  • биологии (наследование, мутации).

Генерация случайных чисел и данных в Python

Как в Python работать со случайными числами

В языке Python существует два основных способа работы со случайными данными: модуль Nympy.random и библиотека random Python.

Модуль Random

Random содержит порядка 20 различных функций для работы со случайными целыми и вещественными числами.

Для работы с ним его нужно импортировать:

import random

В качестве первого примера обычно приводят функцию random() – генерирует вещественное число в отрезке от 0 до 1:

print (random.random())

  • 0.17689854910005198

Для запоминания конкретного числа существует метод seed(). Это своего рода метка, с помощью которой можно вновь воспроизвести значение, сохраненное в памяти:

random.seed (1488)

print(random.random())

print(random.random())

random.seed(1488)

print(random.random())

  • 0.2750168266116314
  • 0.1435651490856893
  • 0.2750168266116314

Чтобы сгенерировать число с плавающей точкой в произвольном промежутке, например от 0 до 100, можно использовать метод uniform():

print(random.uniform(0, 100))

  • 75.1112561853534

Создавать целые числа можно при помощи randint() – отрезок, randrange() – интервал:

print(random.randint(0, 100))

print(random.randrange(0, 100))

  • 85
  • 41

Метод randrange() позволяет также определить шаг интервала:

print(random.randrange(0, 100, 10))

print(random.randrange(0, 100, 10))

  • 80
  • 30

Одна из распространенных задач, которую могут дать на собеседовании, – случайный выбор из списка. Допустим, в коробке находятся 3 белых шара и один черный. Какова вероятность вытащить черный? Для этого потребуется создать цикл из большого количества повторений (хотя бы 1000) и разделить количество выбранных черных шаров на общее количество повторений:

import random

number = 1000

black_num = 0

for i in range(0,number):

ball = random.choice([‘black’, ‘white’, ‘white’, ‘white’])

if ball == ‘black’:

black_num += 1

print (black_num / number)

  • 0.243

Как видим, ответ получился недалеким от истины – 0,25.

Вывод случайным образом нескольких элементов последовательности списка осуществляется при помощи sample():

list_of_nums = [1, 2, 3, 4, 5, 6]

print(random.sample(list_of_nums, 4))

  • [2, 3, 5, 4]

Как видим, получилась новая последовательность, где каждое число было сформировано случайным образом без повторов.

Помимо случайной выборки можно перемешать элементы последовательности чисел списка случайным образом с помощью shuffle():

list_of_nums = [1, 2, 3, 4, 5, 6]

random.shuffle(list_of_nums)

print(list_of_nums)

  • [6, 1, 2, 4, 5, 3]

Рассмотрим еще одну задачу. На этот раз нам будут известны веса событий. Допустим, у нас есть такой «крапленый» игральный кубик, где стороны выпадают с разными вероятностями:

  • 1 – p = 0,05;
  • 2 – p = 0,05;
  • 3 – p = 0,1;
  • 4 – p = 0,2;
  • 5 – p = 0,2;
  • 6 – p = 0,4.

Как в Python работать со случайными числами

Требуется определить количество выпадений шестерок из, допустим, 10 000 бросков:

import random

nums = 10000

six_count = 0

for i in range(0,nums):

cube_side = random.choices([‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’],

weights = [0.05, 0.05, 0.1, 0.2, 0.2, 0.4])

if cube_side == [‘6’]:

six_count += 1

print (six_count)

  • 3957

В этот раз мы использовали метод choices, в который дополнительно можно передать веса weights вероятностных событий.

Numpy.Random

Используется при необходимости генерации массива псевдослучайных чисел:

import numpy

# Матрица размерностью 3×3 значений с плавающей точкой от 0 до 1

rand_arr = numpy.random.rand(3, 3)

print (rand_arr)

  • [[0.03449598 0.88556689 0.66734693]

[0.82412437 0.66913243 0.70730428]

[0.69094665 0.09120329 0.034072 ]]

# Матрицу размером 3×3 случайных вещественных чисел в промежутке от 0 до 100

rand_arr = numpy.random.uniform(0, 100, size = (3, 3))

print (rand_arr)

  • [[76.09088217 52.40791111 15.93937122]
  • [ 6.13460555 38.29344245 74.68885777]
  • [79.71226036 98.59500501 50.48377588]]

# Массив размером 3×3 псевдослучайных целых чисел в заданном диапазоне от 0 до 100

rand_arr = numpy.random.randint(0, 100, size = (3, 3))

print (rand_arr)

  • [[93 73 11]
  • [81 9 96]
  • [89 96 43]]

Случайная строка

Помимо чисел можно генерировать случайно еще буквы:

import random

import string

letter = string.ascii_letters

rand_ascii = random.choice(letter)

print(rand_ascii)

  • f

Или целые строки:

letter = string.ascii_letters

rand_string = ».join(random.choice(letter) for i in range(10))

print(rand_string)

  • rplmzkmget

Криптографическая генерация случайных данных

Как в Python работать со случайными числами

Для того чтобы генерировать криптографически стойкие случайные данные (числа, символы), например для создания паролей, можно использовать несколько методов:

  • модуль secrets – генерирует случайные байты;
  • модуль os.urandom() и SystemRandom() – генерируемые данные привязаны к конкретной операционной системе.

Примеры:

import random

import string

letter = string.ascii_lowercase

# Случайно сгенерированная надежная строка

rand_string = ».join(random.SystemRandom().choice(letter) for i in range(10))

print(rand_string)

  • Omqbcwkwtq

import secrets

letter = secrets.token_bytes(10) # случайные байты

print (letter)

letter = secrets.token_hex(10) # случайная строка в 16-ричной форме

print (letter)

letter = secrets.token_urlsafe(10) # случайная URL-строка

print (letter)

  • b’x9cx17zx94Tnx91;v<‘
  • 0bcc1e558af5f9f77112
  • 528854MP3gZ5iA

Например, можно сгенерировать случайный пароль следующим образом:

import random

import string

import secrets

symbols = string.ascii_letters + string.digits

key_word = ».join(secrets.choice(symbols) for i in range(10))

print(key_word)

  • OrRwiG4nJ8

Более подробно ознакомиться с возможностями использования случайных данных при решении статистических и криптографических задач, с которыми программистам приходится сталкиваться в работе, разобрать таски, часто используемые в тестировании на собеседовании, можно на курсах DevEducation. Здесь на практических примерах поясняются тонкости и аспекты использования тех или иных возможностей языка.

Присоединяйся к DevEducation — стань востребованным специалистом и построй карьеру в IT!