5

I need to generate a list which will have random alphanumeric string of fixed length. It will be something like: list = ['ag5','5b9','c85'] I can make the list with random numbers, but I can't work out to make strings which will have both numbers and letters.The list will have fixed length(say 100 item). I am using python 3.

Iron Fist
  • 10,739
  • 2
  • 18
  • 34
Aman
  • 109
  • 1
  • 1
  • 7
  • What's the size of each element of the list? – Iron Fist Dec 27 '15 at 21:26
  • 1
    Try googling "generate random alphanumeric string python." – intboolstring Dec 27 '15 at 21:29
  • @intboolstring...not quietly..OP wants mix of alphanumeric characters.. – Iron Fist Dec 27 '15 at 21:31
  • 2
    Are the codes supposed to be unique? – Malik Brahimi Dec 27 '15 at 21:38
  • Please google before asking. What have you tried? – Vlad M Dec 27 '15 at 21:58
  • Not necessary to be strictly unique. 1 or 2 repetition in 100 strings will work too. – Aman Dec 27 '15 at 22:01
  • @IronFist, each element needs to be 3 character long and need to have both letters and numbers. I have googled it but most are about numeric random numbers and in case of alphaneumeric strings i can't generate those in list. I'm completely new in python, so some terms seem completely alien to me at present. – Aman Dec 27 '15 at 22:05
  • By "need to have both letters and numbers", do you mean that *every single string* needs to have both? So that "a89" is okay and "99z", but not "abc" or "123"? – DSM Dec 27 '15 at 22:06

4 Answers4

11

To obtain the set of alphanumeric characters you can combine constants from the string module. Then you can use random.choice() in a list comprehension to generate the list:

from random import choice
from string import ascii_lowercase, digits

chars = ascii_lowercase + digits
lst = [''.join(choice(chars) for _ in range(2)) for _ in range(100)]
print(lst)
Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
0

Since you need every single string to have both a letter and a number, we need to do a little more work than usual. We can either keep generating random words and only accept the ones which satisfy our constraint, or we can build a collection of characters that satisfies the constraint by construction.

from random import choice, shuffle
from string import digits, ascii_lowercase

def gen_word(N, min_N_digits, min_N_lower):
    choose_from = [digits]*min_N_dig + [ascii_lowercase]*min_N_low
    choose_from.extend([digits + ascii_lowercase] * (N-min_N_low-min_N_dig))
    chars = [choice(bet) for bet in choose_from]
    shuffle(chars)
    return ''.join(chars)

def gen_word_rejection(N, min_N_digits, min_N_lower):
    bet = digits + ascii_lowercase
    while True:
        word = ''.join([choice(bet) for i in range(N)])
        if (sum(c.isdigit() for c in word) >= min_N_digits and
            sum(c.islower() for c in word) >= min_N_lower):
            return word

which gives me

>>> [gen_word(3, 1, 1) for i in range(5)]
['mb6', 'g4b', 'y5g', '28p', 'ki2']
>>> [gen_word_rejection(3, 1, 1) for i in range(5)]
['y37', 'dr0', 'w1z', 'h2a', 'i6r']

All of which have at least one digit and at least one lowercase letter.

DSM
  • 342,061
  • 65
  • 592
  • 494
-1

I would recommend the hashids with a minimum length of three and a custom salt if you would like:

codes = [hasher.encode(i) for i in range(100)] # assuming hasher = hashids.Hashids('', 3)
Malik Brahimi
  • 16,341
  • 7
  • 39
  • 70
  • Because this is a hashing technique, resultant hashcodes won't be very random if you continue to use the same salt. I strongly suggest the use of a randomly generated salt. – Malik Brahimi Dec 27 '15 at 21:36
-1

I think, you want something like below:

>>> import string
>>> import random
>>> L1 = []
>>> my_chars = string.ascii_lowercase + string.digits #list of alphanumeric characters
>>> while(len(L1)<100): #To keep iterating until len(L1)=100
    s = random.sample(my_chars,3) #Pick a sample(list) of three characters len from chars list
    if not all(t in string.digits for t in s) and not all(t in string.ascii_lowercase for t in s): #Check if these characters are neither only digits nor letters, only mix of both will be allowed
        L1.append(''.join(s)) #concatenate the characters to form the string and add it to list L1


>>> len(L1)
100
>>> L1
['f3m', 'gw2', '9ua', 'm4r', 'fv5', 'jw1', 'd1b', 'lh1', 'i61', '53m', 'j6y', 'fg6', '90d', 'xz1', 'n9f', 'k6r', '31b', 'm8w', '8w1', 'h5q', 'h3d', 'ju2', 'q1i', '6ci', '07m', '40c', 's0h', 'q1p', 'u2o', 'r4g', '6gq', 'rj4', '08x', 'yr6', 'il7', '21w', 'v3q', 'kv9', 'e4i', 'g3o', 'r2p', 'nl7', 'k8h', 'by9', 'qd1', 't71', 'x8f', 'uq3', 'k2z', '5i7', '7pc', 'd68', '6n0', '81y', 'c34', 'la0', 'a0c', '1d9', '7oi', 'z7x', '8l9', '0te', 'e9b', '2yp', '17h', 'vm1', 'vm1', 'ow9', '1ma', 'y7q', '7wa', 'a6b', '9uo', '5t2', 'i40', 'ja1', '16v', '0fe', '6bc', 'ek3', 'th6', '26g', 'a9n', 'fo5', '3hg', '4wz', 'v6z', 'r7b', '9cr', 'a0s', '8yp', 'v0f', 'es4', '8do', 'd0e', 'o6z', 'x3q', 'qw3', 'gi0', '0eg']
Iron Fist
  • 10,739
  • 2
  • 18
  • 34
  • Yes, it works more like i wanted. I have now added ascii_uppercase with it. Thanks. – Aman Dec 27 '15 at 22:49
  • just found a problem with this code. The list is supposed to have 100 alphanumeric string as list element. But each time i run it, the list length is changing randomly, mostly within the range of 50 to 70. I mean sometimes the list contains 53 item, sometimes 68 or so on. The i in range(100) is supposed to generate 100 strings, but i can't understand why it isn't happening. Could you help please? – Aman Dec 28 '15 at 07:09
  • @Aman...Yes I've update the answer..Actually it should be a `while` loop... – Iron Fist Dec 28 '15 at 08:13
  • Why down vote?..Please comment.. – Iron Fist Dec 28 '15 at 11:32