1

I am making a procedural generator for NPCs and am having trouble with getting them to have children.

My code for generating founders (those with arbitrary birth dates rather than driven by a pregnancy algorithm) works fine

#Make Founders
for x in range (NumberOfFounders):
    y = str(x)
    z = 'Person' + y
    ListOfPeople.extend([z])
    ListOfPeople[x] = Person(random.choice(ListOfNames), random.choice(ListOfNames), random.choice(ListOfNames), random.randint(1,10957), 'Null', 'Null', random.randint(0,1))

But when I tried to use similar code to make offspring I get "IndexError: list assignment index out of range" from

q = len(ListOfPeople) + 1
r = str(q)
s = 'Person' + r
ListOfPeople.extend([s])
ListOfPeople[q] = Person(random.choice(ListOfNames1), 'NameMother', 'NameFather', CurrentDate, 'Father', 'Mother', 1)

I will post more code if it is needed.

Thanks.

2 Answers2

1

Given ListOfPeople has length k after generating the founders, then q is assigned to k + 1.

The expression ListOfPeople.extend([s]) (which should probably be replaced with ListOfPeople.append(s)) will cause ListOfPeople to have length k + 1.

A list with k + 1 elements can only be indexed between 0 and k. You try indexing it with q, which equals k + 1, causing IndexError to be be raised.

Tagc
  • 8,736
  • 7
  • 61
  • 114
  • Thanks for your help. What would be the advantage of append over extend? – Brendan Sleanbeck Jan 08 '17 at 20:01
  • @BrendanSleanbeck It's a method that specifically exists for the common use-case of adding one element to the end of an array. Using it makes your intent clearer and is the preferred approach. – Tagc Jan 08 '17 at 20:04
  • I chose to use extend after reading [this](http://stackoverflow.com/questions/252703/append-vs-extend). My understanding was that append was adding a list within the list (hence the square brackets), but extend just added on to the list. – Brendan Sleanbeck Jan 08 '17 at 20:08
  • No, `l.append(o)` will just add object `o` to the end of list `l`. A list will only be added within a list if `o` is a list itself. – Tagc Jan 08 '17 at 20:10
0

If you add a few prints to your code, it is pretty obvious.

Say ListOfPeople is [Person_1, Person_2, Person_3]

q = len(ListOfPeople) + 1
# q = 4
r = str(q)
# r = '4'
s = 'Person' + r
# s = 'Person4'
ListOfPeople.extend([s])
# ListOfPeople = [Person_1, Person_2, Person_3, 'Person4']
ListOfPeople[q] = Person(random.choice(ListOfNames1), 'NameMother', 'NameFather',
# Index error because ListOfPeople[q] does not exist

What are you trying to achieve, anyway? Append 'Person4' temporarily then replace that last item with a real Person instance in the next statement?

It does not seem to make sense, but maybe this is because you simplified your code for the purpose of your question.

Anyway, if I understand correctly, you could do all that in just one line:

ListOfPeople.append(Person(random.choice(ListOfNames1), 'NameMother', 'NameFather',)

BTW, here's a few tips:

Formatting a string with a number. No need to "cast" as str explicitly. You may use q directly:

s = 'Person%s' % q
s = 'Person{}'.format(q)

Accessing last element of a list. No need to get the length or the list and compute the index of the last element. Use negative indexing:

ListOfPeople[-1] = whatever...

Appending to a List. No need to create a list and call extend. Just call append:

ListOfPeople.append(s)
Jérôme
  • 13,328
  • 7
  • 56
  • 106