0

I need help trying to understand why this function returns forenames surnames instead of names. It's the first for loop that's got me confused I believe. For some background, the paths in the first for loop are just text files that list different names, one per line. Why are we returning forenames and surnames when each name from the files are being appended into the names variable? Please help, and let me know if more information is needed.

import random

def get_forenames_and_surnames():
    forenames = []
    surnames = []
    for names, filename in ((forenames, "/home/mmelv/eclipse-
                                workspace/py30eg/data/forenames.txt"),
                        (surnames, "/home/mmelv/eclipse-
                                workspace/py30eg/data/surnames.txt")):
        with open(filename, encoding="utf8") as file:
            for name in file:
                names.append(name.rstrip())
    return forenames, surnames


forenames, surnames = get_forenames_and_surnames()
with open("test-names1.txt", "w", encoding="utf8") as file:
    for i in range(100):
        line = "{0} {1}\n".format(random.choice(forenames),
                                  random.choice(surnames))
        file.write(line)

The file for with list of forenames looks like:

Ailish
Cayden
Cohen
Maison
Becky
Dodou
Nickie
Zachary
Climate

The file with a list of surnames is the same but with different names.

MMelvin0581
  • 509
  • 6
  • 20

2 Answers2

0

understand why this function returns forenames surnames instead of names

Well... return forenames, surnames is why it does. And the formatting at the bottom requires two separate lists. (And return names would actually return surnames)

The loop is doing tuple-unpacking. Each iteration, you unpack one tuple and assign names, filename. Since the names is a list reference, names.append() will operate the same as forenames.append(), or surnames.append() depending on the iteration.

FWIW, you could rewrite the first function to use two explicit loops per file.

def get_forenames_and_surnames():
    forenames = [line.rstrip() for line in open("/home/mmelv/eclipse-workspace/py30eg/data/forenames.txt", encoding="utf8")]
    surnames = [line.rstrip() for line in open("/home/mmelv/eclipse-workspace/py30eg/data/surnames.txt", encoding="utf8")]
    return forenames, surnames

If you wanted to use one list, take a look at the zip() function.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • See now that makes more sense. I get the job of the return statement btw, I'm not that green lol. Still shaky on the way the book had it written, but I understand your code just find. I guess it's the tuple unpacking I'm not comprehending. – MMelvin0581 Nov 16 '17 at 04:29
  • 1
    https://stackoverflow.com/questions/10867882/tuple-unpacking-in-for-loops – OneCricketeer Nov 16 '17 at 04:30
0

what it is returning is essentially this:

(['Ailish', 'Cayden', 'Cohen', 'Maison', 'Becky', 'Dodou', 'Nickie', 'Zachary', 'Climate'],
['Ailish2', 'Cayden2', 'Cohen2', 'Maison2', 'Becky2', 'Dodou2', 'Nickie2', 'Zachary2',
'Climate2'])

so you are getting a tuple with two objects in it, each object is a list of names the first list in the tuple being named forenames and the second named surnames.

The end part of that code you wrote is just taking a random name from the first list of names and matching it with a random name from the second list of names.