pythonlistrandomlambda

Having an item in a list randomly select an item from another list whenever it is randomly selected from the first


I am trying to write a function that generates a random name by selecting a first name from one list and a last name from another list. I want the last item in the last name list to randomly select an item from the first name list, concatenate it with 'son', and then provide the resulting string. I want it to be a different result each time the item is selected- ie 'Richardson' one time and 'Jacksonson' the next.

I tried making the last item random.choice(first_names) + 'son', which gives me the same result each time. I also tried making it lambda:random.choice(first_names) + 'son', which gives me the identifier of the lambda function <function <lambda> at [0xnumbers I'm not sharing]>. It gives me the result I want if I use parentheses after the index, but that means that if the code selects one of the other results, it throws an error. My code looks sort of like this (albeit with longer lists, but otherwise identical):

import random

first_names = ['James','Ida','Crocodile']
last_names = ['Smith','Williams','Ramos',lambda:random.choice(first_names) + 'son']

print(last_names[-1]())
print(last_names[-1]()) #to check if it has the same result every time
                        #this is a lot less likely in my actual code, since there's >100 names

Solution

  • Tim Roberts's answer is probably what I would go with.

    If you're absolutely bent on having last_names be a list for some reason, I suppose you can define a LastNameGenerator class that stores a list of first names and picks one at random when its __str__ method is called.

    import random
    
    class LastNameGenerator:
        def __init__(self, first_names):
            self.first_names = first_names.copy()
    
        def __str__(self):
            return random.choice(first_names) + 'son'
    
    first_names = ['James','Ida','Crocodile']
    last_names = ['Smith','Williams','Ramos', LastNameGenerator(first_names)]
    

    This has the unfortunate downside of, well, not being a string. If you want your code to work reliably, you'll have to manually call str() on the generated last name to make sure it's the right type. Otherwise, you'll likely run into a lot of TypeErrors.

    print(last_names[-1]) # Fine since print() calls __str__ implicitly
    print("Ida " + str(last_names[-1])) # Fine since str() is being called manually
    print("Crocodile " + last_names[-1]) # TypeError: can only concatenate str (not "LastNameGenerator") to str