简体   繁体   中英

Permutations with multiple list and Conditions

I want to generate list of all possible Strings of each 5 character permutation of two list

List 1: [A-Z] all caps Alphabets
List 2: [0-9] Digits

conditions of string

  1. Each string must contain min. of 1 digit and min. of 1 Alphabet
  2. Each string must not contain more than 3 of same (Digit/Alphabet)

Example Outputs:

B9B61
6F084
7C9DA
9ECF9
E7ACF

i tried this but i know i could not apply conditions so far, pretty confused right now kindly help

from itertools import permutations 

perm = [''.join(p) for p in permutations('ABCDEFGHIJKLMOPQRSTUVWXYZ0123456789', 5)] 

for i in list(perm): 
    with open("list.txt", "a+") as file:
        file.write(i)
        file.write("\n")

The following will print out all 5 char combinations of all uppercase letters and digits with no more than 3 of any char or digit.

import string
import itertools
possible_combinations = itertools.permutations(string.ascii_uppercase * 3 + string.digits * 3, 5)
for possible_str in (''.join(chars) for chars in possible_combinations):
    if possible_str.isnumeric() or possible_str.isalpha():
        continue
    else:
       print(possible_str)

To get all combinations of letters and digits with no more than 3 repeated first we look at itertools.permutations . Given an iterable of chars (a string) it will return all combinations of those chars for the given length

>>> [''.join(x) for x in itertools.permutations('ABC', 3)]
['ABC', 'ACB', 'BAC', 'BCA', 'CAB', 'CBA']

If we pass 2 of each char, permutations will return all combinations with up to 2 of every char

>>> [''.join(x) for x in itertools.permutations('AABBCC', 3)]
['AAB', 'AAB', 'AAC', 'AAC', 'ABA', 'ABB', 'ABC', 'ABC', 'ABA', 'ABB', 'ABC', 'ABC', 'ACA', 'ACB', 'ACB', 'ACC', 'ACA', 'ACB', 'ACB', 'ACC', 'AAB', 'AAB', 'AAC', 'AAC', 'ABA', 'ABB', 'ABC', 'ABC', 'ABA', 'ABB', 'ABC', 'ABC', 'ACA', 'ACB', 'ACB', 'ACC', 'ACA', 'ACB', 'ACB', 'ACC', 'BAA', 'BAB', 'BAC', 'BAC', 'BAA', 'BAB', 'BAC', 'BAC', 'BBA', 'BBA', 'BBC', 'BBC', 'BCA', 'BCA', 'BCB', 'BCC', 'BCA', 'BCA', 'BCB', 'BCC', 'BAA', 'BAB', 'BAC', 'BAC', 'BAA', 'BAB', 'BAC', 'BAC', 'BBA', 'BBA', 'BBC', 'BBC', 'BCA', 'BCA', 'BCB', 'BCC', 'BCA', 'BCA', 'BCB', 'BCC', 'CAA', 'CAB', 'CAB', 'CAC', 'CAA', 'CAB', 'CAB', 'CAC', 'CBA', 'CBA', 'CBB', 'CBC', 'CBA', 'CBA', 'CBB', 'CBC', 'CCA', 'CCA', 'CCB', 'CCB', 'CAA', 'CAB', 'CAB', 'CAC', 'CAA', 'CAB', 'CAB', 'CAC', 'CBA', 'CBA', 'CBB', 'CBC', 'CBA', 'CBA', 'CBB', 'CBC', 'CCA', 'CCA', 'CCB', 'CCB']

The same holds true if we increase the number of chars and how many we repeat them by. So we have string.ascii_uppercase * 3 + string.digits * 3 which returns a string with all uppercase letters repeated 3 times and all digits repeated 3 times

The last thing to do it filter out strings with no digits or letters in them. string.isnumeric() returns true if all chars are digits and string.isalpha() returns true if all chars are letters

You can go with your permutations by applying some checks:

from itertools import permutations
from collections import Counter

for i in permutations('ABCDEFGHIJKLMOPQRSTUVWXYZ0123456789', 5):
    combo = "".join(i)
    result = Counter(i)
    if any(s>=3 for s in result.values()) \
            or sum(c.isdigit() for c in i)<1 \
            or sum(c.isalpha() for c in i)<1:
        continue
    print (combo)
import random 

output = [] #always initiate as empty

alphanum = ['A','B','C','D','E','F','G','H','I','J','K','L','M','O','P','Q','R','S','T','U','V','W','X','Y','Z',0,1,2,3,4,5,6,7,8,9]

while len(output) < 5:#5 is max

    output.append(random.choice(alphanum)) #pick random from list

    counter_i = counter_s = 0 #counter for integers and characters

    for element in output:

        if isinstance(element,int): 

            counter_i +=1

        elif isinstance(element,str):

            counter_s +=1

        if (counter_i > 3 or counter_s >3) : #max 3  for numbers or strings

            output.pop() #remove from list if it exceeds the limits


print(output)       
['M', 'Z', 4, 'B', 9]

result = '' 
for l in output:
    result +=str(l)

print(result)
MZ4B9

you can try this function. it returns unique and least one alphabet and one digit.

import random 

alphabets = "ABCDEFGHIJKLMOPQRSTUVWXYZ" 
digits = "0123456789"

def generate_code(length):
    alp_len = random.randint(1,length-1)
    dig_len = length-alp_len

    selected = list(random.sample(alphabets,alp_len))
    selected.extend (random.sample(digits,dig_len))

    random.shuffle ( selected ) 

    return ''.join(selected) 


print (generate_code(5))

random.sample(population, k)

Return ak length list of unique elements chosen from the population sequence. Used for random sampling without replacement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM