Рубрики
Без рубрики

Больше практики Python: Найдите случайное число (Ft. Sets!)

<< Неделя 13: дайвинг доска | Просмотреть решение на GitHub | Неделя 15: бинарные деревья ... Tagged с Python, Codenewbie, Computerscience, новичками.

<< Неделя 13: дайвинг доска | Просмотреть решение на GitHub | Неделя 15: бинарные деревья >>

Cloudflare в Сан -Франциско использует Лава лампы В качестве генератора случайных чисел для зашиваний зашифрует (Источник: Fast Company)

Случайные числа, специя жизни. Или, по крайней мере, в мире кодирования, они есть. Скучно API Использует случайные числа, чтобы найти деятельность, чтобы облегчить вашу скуку, а такие игры, как Minecraft, используют их для порождения случайной местности (посмотрите мой простой 2D JavaScript Minecraft. Здесь ) И есть более практические применения, такие как шифрование в Cloudflare, в котором используется Стена лавовых ламп в качестве генератора случайных чисел для шифрования веб -запросов.

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

# Given an integer n and a list of integers, 
# write a function that randomly generates a number 
# from 0 to n-1 that isn't in the list.

Есть две вещи, которые нам понадобятся, если мы собираемся генерировать случайное целое число. Один – это питон случайный Библиотека, и нам также понадобится Математика Библиотека, чтобы завершить наше случайное число до целого числа.

import random
import math

Далее, как всегда, мы определяем наш метод. Это требует числа и списка целых чисел, которые мы будем называть Nums Анкет

def get_rand(n, nums):
    pass

Решение 1: повторный

Давайте поговорим о стратегии. Первый, который мы обсудим, – это идея «галактик мозг», которая, возможно, сначала приходит на ум: найдите случайное число в данном диапазоне, а затем, если оно будет в списке, просто запустите генератор случайных чисел, пока мы не найдем тот, который действителен.

Мы начнем с получения случайного числа от 0 до н. случайный У объекта есть метод под названием random () который возвращает случайное (десятичное) число от 0 до 1. Чтобы получить число от 0 до N, мы умножаем его на n, а затем мы округлите, используя math.floor ()

  rand_num = math.floor(random.random() * n)

Вы можете начать с получения случайного числа, но есть еще кое -что, что мы можем использовать, чтобы сделать (довольно ужасное) время выполнения немного лучше. Давайте посмотрим на что -то, что используется во многих языках программирования, называемых набором.

Установить – Тип данных, который хранит уникальные значения в любом конкретном порядке.

Визуализация установленного данных.

Мне нравится думать о наборах как облаке: куча чисел, плавающих вокруг, но им нет никакого порядка. Важно, чтобы ни одно число не появляется дважды. Если вы попытаетесь добавить 3 в набор, и он уже там, он больше не будет добавлен. Что для нас полезно, так это то, что проверка, чтобы увидеть, содержит ли набор определенное число, требуется постоянное время O (1). Это лучше, чем O (n) время, которое мы получили бы, если бы нам пришлось каждый раз проходить список.

Как мы реализуем набор в Python? Начните с вызова класса SET с его конструктором, set () Анкет

  s = set()

Далее мы добавляем номера из списка в набор.

for num in nums:
    s.add(num)

Теперь мы проверяем, находится ли в наборе случайное число. Если нет, мы хотим найти новое случайное число. Это может быть достигнуто с помощью В то время как Цикл, который работает, если случайное число находится в наборе. Для развлечения вы можете поместить заявление о печати, чтобы увидеть, сколько раз метод должен найти новый номер, прежде чем он найдет тот, который будет действительным.

  while rand_num in s:
    print("reroll")
    rand_num = math.floor(random.random()*n)

И, наконец, мы возвращаем полученное случайное число, как только В то время как петля была выведена. Вообще:

def get_rand(n, nums):
  rand_num = math.floor(random.random()*n)
  s = set()
  for num in nums:
    s.add(num)
  while rand_num in s:
    print("reroll")
    rand_num = math.floor(random.random()*n)
  return rand_num

Если мы попробуем это печатать get_rand (5, [0, 1, 2, 3]) , мы должны получить 4, что является единственным оставшимся числом, которое меньше 5, и этого не в списке.

Как я упоминал ранее, время выполнения этого решения не очень эффективно. Потенциально, алгоритм может продолжать выбирать случайные числа в вечность, если он не найдет правильного-это именно то, что произойдет, если есть являются Нет цифр, которые соответствуют критериям. Почему бы тебе не попробовать печатать результат get_rand (5, [0, 1, 2, 3, 4]) , где список содержит все числа, которые меньше 5. Это выглядит так?

reroll
reroll
reroll  
reroll
reroll
reroll
reroll
...

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

Решение 2: Список возможных чисел

Иногда мы подходим к этим вопросам программирования, как будто мы решаем математическую программу, и забываем: мы Разработчики . Мы строить вещи Анкет Итак, один подход всегда спрашивать: «Могу ли я построить то, что мне нужно, чтобы решить эту проблему?»

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

Первая часть нашего метода останется прежней: мы берем числа из Nums Список и поместите их в набор. Затем мы хотим составить пустой список, который будет содержать все возможные номера на выбор.

def get_rand2(n, nums):
  s = set()
  for num in nums:
    s.add(num)
  poss_nums = []

Как мы находим действительные числа? Мы просто пробираемся через каждое целое число от 0 до n , и если его нет в наборе, мы добавляем его в список.

  for num in range(n):
    if num not in s:
      poss_nums.append(num)

Если бы мы запустили наш звонок ранее, get_rand (5, [0, 1, 2, 3]) , мы получили бы список SOSS_NUMS содержащий только номер 4.

Далее мы проверяем на нашем крае. Просто проверьте, пуст ли список, и если да, верните Нет Анкет

  if not len(poss_nums):
    return None

Что осталось? Чтобы выбрать наше случайное число, конечно! Используя random.random () Функция, мы умножаем его на длину списка, чтобы выбрать случайный индекс, а затем вернем число в этом индексе.

  rand_i = math.floor(random.random()*len(poss_nums))
  return poss_nums[rand_i]

Вот и все! Метод выглядит в целом:

def get_rand2(n, nums):
  s = set()
  for num in nums:
    s.add(num)
  poss_nums = []
  for num in range(n):
    if num not in s:
      poss_nums.append(num)
  if not len(poss_nums):
    return None
  rand_i = math.floor(random.random()*len(poss_nums))
  return poss_nums[rand_i]

Теперь, если мы попробуем запустить get_rand (5, [0, 1, 2, 3, 4]) И распечатать результат, мы не должны получить ни одного, потому что нет цифр, которые соответствуют критериям. Ура! Нет больше бесконечных петлей.

Это все для этой недели. Если вам нравится этот контент, пожалуйста, дайте мне знать в комментариях, что вы хотели бы увидеть дальше!

<< Неделя 13: дайвинг доска | Просмотреть решение на GitHub | Неделя 15: бинарные деревья >>

Шеймус Хейккила ранее был ассистентом преподавателя в Генеральной Ассамблее. Этот блог не связан с GA.

Оригинал: “https://dev.to/pythonwb/more-python-practice-find-the-random-number-ft-sets-50lf”