Таким образом, используя код, который у меня есть, при генерации числовой / буквенной строки он генерирует дополнительную черту в конце, и я хочу, чтобы она состояла только из 16 цифр и букв (без дополнительной черты)

import string, random

def generateCode():
    code = ''
    for i in xrange(16):
        number = random.choice(string.ascii_letters + string.digits)
        code += str(number)
        if (i - 3) % 4 == 0 and i - 4:
            code += '-'

    file = open('AlphaKeys.txt', 'w')
    file.write(code + '\n')
    file.close()
    return code

generateCode()

И пример вывода: qIss-wXbS-PZo7-audg-

0
legacy 27 Авг 2017 в 23:07

4 ответа

Лучший ответ

Второе условие в вашем выражении if не имеет смысла. Вы должны просто изменить его, чтобы не добавлять -, если вы находитесь на последней итерации:

if (i - 3) % 4 == 0 and i < 15:
    ...

Внесение этого изменения дает мне:

LjIs-6HT5-zZMD-HMMz

Могу ли я предложить улучшение по сравнению с вашим текущим подходом с помощью random.sample ?

import random

r = string.ascii_letters + string.digits
string =  '-'.join(''.join(random.sample(r, 4)) for _ in range(4))
print(string)

'fiqc-fvbc-z7s9-62w3'

Обратите внимание, что random.sample не предлагает замену для каждого вызова, поэтому, если вы этого хотите, вам потребуется random.choice.

Если вам нужна случайность с заменой, вы можете заменить random.sample на random.choices - но только с python3.6 и выше.

0
cs95 27 Авг 2017 в 20:26

Конечно, вы добавляете тире даже на последней итерации.

В любом случае, самый питонический способ: просто вложите 2 str.join выражения:

import string,random

code = "-".join(["".join([random.choice(string.ascii_letters + string.digits) for _ in range(4)]) for _ in range(4)])

print(code)

Пример:

m7b1-A0vS-JARQ-hlo2

Внутреннее сжатие генерирует последовательность из 4 букв и цифр, а внешнее объединяет 4 из этих последовательностей с -.

Обратите внимание, что синтаксис join([..]) может показаться громоздким, но он быстрее, чем без квадратных скобок (Присоединение к строкам. Генератор или понимание списка?)

РЕДАКТИРОВАТЬ: обратите внимание, что ваши цифры / буквы могут повторяться с random.choice. Лучший подход без повторов - использовать random.choice следующим образом:

import string,random

it = iter(random.sample(string.ascii_letters + string.digits,16))

code = "".join(["-" if i % 5 == 4 else next(it) for i in range(19)])

Итератор используется, кроме случаев, когда пришло время выдавать тире.

0
Jean-François Fabre 27 Авг 2017 в 20:24

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

if i and i % 4 == 0:
     code+= '-'
number = random.choice(string.ascii_letters + string.digits)
code += str(number)

Что немного более читабельно, чем после

if (i - 3) % 4 == 0 and i < 15: code+= '-'

Но в целом использование соединения было бы более питонным, например.

def code_part():
    return ''.join(random.choice(string.ascii_letters + string.digits) 
                   for i in xrange(4))
'-'.join(code_part() for i in xrange(4))
0
meili 27 Авг 2017 в 20:32

Еще одна альтернатива, только с одним циклом:

import string,random
possible_chars = string.ascii_letters + string.digits
"".join(random.choice(possible_chars) if i % 5 < 4 else '-' for i in range(19))
#=> '4Mhg-flw1-lUEu-pu3h'
0
Eric Duminil 27 Авг 2017 в 20:20