Büyük harf ve rakamlarla rastgele dize oluşturma

N boyutunda bir dize oluşturmak istiyorum.

Rakamlardan ve aşağıdaki gibi büyük İngilizce harflerden oluşmalıdır:

  • 6U1S75
  • 4Z4UKK
  • U911K4

Bunu pythonic bir şekilde nasıl başarabilirim?

Çözüm

Tek satırda cevap verin:

''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))

veya Python 3.6 ile başlayarak random.choices() kullanarak daha da kısaltabilirsiniz:

''.join(random.choices(string.ascii_uppercase + string.digits, k=N))

Kriptografik olarak daha güvenli bir sürüm; bkz. https://stackoverflow.com/a/23728630/2213647:

''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))

Daha fazla yeniden kullanım için temiz bir işlevle ayrıntılı olarak:

>>> import string
>>> import random
>>> def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
...    return ''.join(random.choice(chars) for _ in range(size))
...
>>> id_generator()
'G5G74W'
>>> id_generator(3, "6793YUIO")
'Y3U'

**Nasıl çalışıyor?

Yaygın ASCII karakter dizilerini içeren bir modül olan string ve rastgele üretimle ilgilenen bir modül olan random modüllerini içe aktarıyoruz.

string.ascii_uppercase + string.digits` sadece büyük harf ASCII karakterlerini ve rakamları temsil eden karakter listesini birleştirir:

>>> string.ascii_uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.digits
'0123456789'
>>> string.ascii_uppercase + string.digits
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'

Daha sonra 'n' elemanlı bir liste oluşturmak için bir liste kavrama kullanırız:

>>> range(4) # range create a list of 'n' numbers
[0, 1, 2, 3]
>>> ['elem' for _ in range(4)] # we use range to create 4 times 'elem'
['elem', 'elem', 'elem', 'elem']

Yukarıdaki örnekte, listeyi oluşturmak için [ kullanıyoruz, ancak id_generator işlevinde kullanmıyoruz, böylece Python listeyi bellekte oluşturmuyor, ancak öğeleri tek tek anında oluşturuyor (bu konuda daha fazla bilgi burada).

Python'dan `elem' karakter dizisini 'n' kez oluşturmasını istemek yerine, bir karakter dizisinden seçilen rastgele bir karakteri 'n' kez oluşturmasını isteyeceğiz:

>>> random.choice("abcde")
'a'
>>> random.choice("abcde")
'd'
>>> random.choice("abcde")
'b'

Bu nedenle random.choice(chars) for _ in range(size) gerçekten size karakterlerinden oluşan bir dizi oluşturmaktadır. Karakterler chars içinden rastgele seçilir:

>>> [random.choice('abcde') for _ in range(3)]
['a', 'b', 'b']
>>> [random.choice('abcde') for _ in range(3)]
['e', 'b', 'e']
>>> [random.choice('abcde') for _ in range(3)]
['d', 'a', 'c']

Daha sonra bunları boş bir dize ile birleştiririz, böylece dizi bir dize haline gelir:

>>> ''.join(['a', 'b', 'b'])
'abb'
>>> [random.choice('abcde') for _ in range(3)]
['d', 'c', 'b']
>>> ''.join(random.choice('abcde') for _ in range(3))
'dac'
Yorumlar (27)

Daha basit, daha hızlı ancak biraz daha az rastgele bir yol, her harfi ayrı ayrı seçmek yerine random.sample kullanmaktır. n-tekrara izin veriliyorsa, rastgele temelinizi n kat büyütün, örn.

import random
import string

char_set = string.ascii_uppercase + string.digits
print ''.join(random.sample(char_set*6, 6))

Not: random.sample karakterin tekrar kullanılmasını önler, karakter kümesinin boyutunu çarpmak birden fazla tekrarı mümkün kılar, ancak yine de saf rastgele bir seçimde olduğundan daha az olasıdırlar. Eğer 6 uzunluğunda bir karakter dizisi seçersek ve ilk karakter olarak 'X' karakterini seçersek, seçim örneğinde, ikinci karakter olarak 'X' karakterini alma olasılığı ilk karakter olarak 'X' karakterini alma olasılığı ile aynıdır. random.sample uygulamasında, sonraki herhangi bir karakter olarak 'X' elde etme olasılığı, ilk karakter olarak elde etme olasılığının yalnızca 6/7'sidir

Yorumlar (10)

Kimsenin buna cevap vermediğini sanıyordum lol! Ama hey, işte benim kendi girişimim:

import random

def random_alphanumeric(limit):
    #ascii alphabet of all alphanumerals
    r = (range(48, 58) + range(65, 91) + range(97, 123))
    random.shuffle(r)
    return reduce(lambda i, s: i + chr(s), r[:random.randint(0, len(r))], "")
Yorumlar (2)