Generate alphanumeric strings sequentially

前端 未结 5 2057
我寻月下人不归
我寻月下人不归 2020-12-25 08:38

I\'m trying to create a loop to generate and print strings as follows:

  1. Alphanumeric characters only:
  2. 0-9 are before A-Z, which are before a-z,
相关标签:
5条回答
  • 2020-12-25 09:29

    I coded this today. It does exactly what you want and more. It's extendable as well

    def lastCase (lst):
        for i in range(0, len(lst)):
            if ( lst[i] != '_' ):
                return False
        return True
    
    
    l = [''] * 4 #change size here if needed. I used 4
    l[0] = '0'
    index = 0
    
    while ( not lastCase(l) ):
    
        if ( ord(l[index]) > ord('_') ):
            l[index] = '0'
            index += 1
            while( l[index] == '_' ):
                l[index] = '0'
                index += 1
            if (l[index] == ''):
                l[index] = '0'
    
        #print or process generated string
        print(''.join(l))
    
        l[index] = chr(ord(l[index]) +1)
    
        if ( ord(l[index]) > ord('9') and ord(l[index]) < ord('A') ):
            l[index] = 'A'
        elif ( ord(l[index]) > ord('Z') and ord(l[index]) < ord('_')  ): 
            l[index] = '_'
    
        index = 0
    
    print (''.join(l))
    
    0 讨论(0)
  • 2020-12-25 09:30
    from string import digits, ascii_uppercase, ascii_lowercase
    from itertools import product
    chars = digits + ascii_uppercase + ascii_lowercase
    
    def give_me_next(lst):
            lst = lst[::-1]
            change_next = False
            change = True
            n = 0
            for x in lst:
                    if change_next == True:
                            change_next = False
                            pos = chars.find(x)
                            try:
                                    a =  chars[pos+1]
                                    lst = list(lst)
                                    lst[n] = a
                                    lst = "".join(lst)
                                    x = a
                            except:
                                    lst = list(lst)
                                    lst[n] = '0'
                                    lst = "".join(lst)
                                    change_next = True
                                    x = '0'
    
                    pos = chars.find(x)
                    try:
                            a =  chars[pos+1]
                            if change == True:
                                    lst = list(lst)
                                    lst[n] = a
                                    lst = "".join(lst)
                                    change = False
                    except:
                            lst = list(lst)
                            lst[n] = '0'
                            lst = "".join(lst)
                            change_next = True
    
                    n = n + 1
    
            lst = lst[::-1]
            return lst
    
    a=  give_me_next('zzzzz')
    while True:
            a =  give_me_next(a)
            print a
    
    0 讨论(0)
  • 2020-12-25 09:33

    I dislike the answer given before me using product since looking at its implementation in the python documentation it seem to span the entire thing into a list in memory before starting to yield the results.

    This is very bad for your case since, as agf himself said, the number of permutation here is huge (well over a million). For this case the yield statement was created - so that huge lists could be dynamically generated rather than spanned in memory (I also disliked the wasteful range where xrange is perfectly applicable).

    I'd go for a solution like this:

    def generate(chars, length, prefix = None):
        if length < 1:
            return
        if not prefix:
            prefix = ''
        for char in chars:
            permutation = prefix + char
            if length == 1:
                yield permutation
            else:
                for sub_permutation in generate(chars, length - 1, prefix = permutation):
                    yield sub_permutation
    

    This way, all that spans in memory is a recursive stack "n" deep, where "n" is the length of your permutations (4 in this case) and only a single element is returned each time.

    chars is the set of chars to choose from, length is 4 and the use is rather similar to products, except that it doesn't span the whole list in memory during run time.

    0 讨论(0)
  • 2020-12-25 09:34
    from string import digits, ascii_uppercase, ascii_lowercase
    from itertools import product
    
    chars = digits + ascii_uppercase + ascii_lowercase
    
    for n in range(1, 4 + 1):
        for comb in product(chars, repeat=n):
            print ''.join(comb)
    

    This first makes a string of all the numbers, uppercase letters, and lowercase letters.

    Then, for each length from 1-4, it prints every possible combination of those numbers and letters.

    Keep in mind this is A LOT of combinations -- 62^4 + 62^3 + 62^2 + 62.

    0 讨论(0)
  • 2020-12-25 09:44

    This seems like the simplest solution to me:

    from string import digits, ascii_uppercase, ascii_lowercase
    
    chars = digits + ascii_uppercase + ascii_lowercase
    all_str = [''.join([a]) for a in chars] \
            + [''.join([a,b]) for a in chars for b in chars] \
            + [''.join([a,b,c]) for a in chars for b in chars for c in chars] \
            + [''.join([a,b,c,d]) for a in chars for b in chars for c in chars for d in chars]
    
    print(all_str)
    print("Number of strings:", len(all_str))
    

    Example for strings with maximum 2 characters.

    Of course, there may be a way to generalize to any max number of characters per string, but since you have a specific need for strings up to 4 characters, it's fine.

    0 讨论(0)
提交回复
热议问题