Основная проблема заключается в том, что вы увеличиваете n
, даже если вы уже добавили элемент в словарь. Поэтому, если вы уже добавили элемент, он все равно считается как один. Если он был добавлен , а не , он считается как два, но, таким образом, возможны случаи, когда
В любом случае, нет никаких причин делать это, мы можем сначала создать случайную строку, перетасовывая символы, а затем «сшить» их вместе, например:
Основная проблема заключается в том, что вы увеличиваете n
, даже если вы уже добавили элемент в словарь. Поэтому, если вы уже добавили элемент, он все равно считается как один. Если он был добавлен , а не , он считается как два, но, таким образом, возможны случаи, когда
В любом случае, нет никаких причин делать это, мы можем сначала создать случайную строку, перетасовывая символы, а затем «сшить» их вместе, например:
from string import ascii_uppercase
from random import shuffle
dt = list(ascii_uppercase)
shuffle(dt)
dt = iter(dt)
result = {k: v for a, b in zip(dt, dt) for k, v in ((a,b), (b, a))}
Или, если персонаж может «спариться» вместе с самим собой, мы можем реализовать его следующим образом:
from string import ascii_uppercase
from random import shuffle, randint
dt = list(ascii_uppercase)
shuffle(dt)
result = {}
i = 0
while i < len(dt):
d = randint(0,len(dt)-i-1 > 0)
k = dt[i]
v = dt[i+d]
result.update({k: v, v: k})
i += 1 + d
assert len(result) == len(ascii_uppercase)
assert len(set(result.values())) == len(ascii_uppercase)
Оба алгоритма работают в линейном времени, поскольку они делают один проход по списку случайных символов и каждый раз связывают предыдущий со следующим символом (или текущий символ с самим собой).