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).