Home > Blockchain >  How to get random names from a list without repeating names. Python
How to get random names from a list without repeating names. Python

Time:12-11

I am very new to Python and I have run into a problem that I can't find the solution for. I am trying to create a unique character generator, to create the names I have a pool of names that are in a .txt file and also suffix' which are in another one. However, I run into the problem that when I run the code sometimes the same names appear as they are chosen at random each time round. This is the code that I have written for it:

import random

a_file = open("Alien_Names.txt", "r")
a_names = [(line.strip()).split() for line in a_file]
a_file.close()

b_file = open("suffix.txt", "r")
b_names = [(line.strip()).split() for line in b_file]
b_file.close()

def repeat():
fname = random.choice(a_names)
sname = random.choice(b_names)
print(fname, sname)
for i in range (10):
repeat()

I will be thankful for any help.

CodePudding user response:

Use random.sample:

for fname, sname in zip(
    random.sample(a_names, 10), 
    random.sample(b_names, 10)
):
    print(fname, sname)

random.sample(a_names, 10) randomly samples 10 different elements from a_names.

CodePudding user response:

You could shuffle each list, then pair them

def generate():
    random.shuffle(a_names)
    random.shuffle(b_names)
    for fname, sname in zip(a_names, b_names):
        print(fname, sname)

Or nicer, and without modifying the lists inplace

def generate():
    for fname, sname in zip(random.sample(a_names, len(a_names)), 
                            random.sample(b_names, len(b_names))):
        print(fname, sname)

CodePudding user response:

You could create infinite generator functions that will loop through the names indefinitely yielding random names. This way, even if you don't have the same number of a_names and b_names, you can get more pairings:

import random

def genNames(fileName): 
    with open(fileName, "r") as namesFile:
        names = [line.strip() for line in namesFile] # load names from file
    while True:               # repeat indefinitely
        random.shuffle(names) # randomize order
        yield from names      # yield all names

def genFullNames():
    iAlienNames = genNames("Alien_Names.txt") # infinite random alien names
    iSuffixes   = genNames("suffix.txt")      # infinite random suffixes
    seen = set()                              # track uniques
    while True:
        fullName = (next(iAlienNames), next(iSuffixes)) # pair up names
        if fullName in seen: continue # never yield same pairing twice
        yield fullName                # return one name when next() is called
        seen.add(fullName)            # remember using that pairing
          

iFullName = genFullNames()  # infinite full name pair iterator

for _ in range(10):
    aName, sName = next(iFullName)
    print(aName, sName)
   

You can use next(iFullName) anywhere in your program where you need a new unique alien name.

This way of randomizing the names ensures that there will rarely be the same Alien name for two consecutive fullNames (and also rarely identical consecutive suffixes). It is still possible though. When the internal while loop of genNames() reshuffles the names, it could happen that the first name is the one that was previously last in the list. e.g. If you have 50 names in the file, this would have a 1-in-50 chance of happening on the 51st, 101st, 151st ... names (genFullNames ensure that the combination will be unique though).

  • Related