hlynurs hlynurs - 25 days ago 5
Python Question

Looping through list in Python

I have a problem where I have a double for loop, going through a list of lists.

My problem is that once I get the first list, and am looping through that list, the very last item there isn't an integer, but a list that contains 0L.

The last three items of the list are the following [...15579L, 58L, 198L]

When printing out each element in the list, I get the following:
...
15579
58
198
[0L]

Does anyone know what's going on here and how I can avoid using that extra item?

This is the loop I currently have:

myList1 = [[] for _ in range(accountMax+1)]
myList2 = list(myList1)
# accountMax is roughly 78000
index=0
for items in myList1:
print('printing list')
print(items)
for account in items:
print('printing account')
print(account)
myList2[index].append(myList1[account])
index = index+1


This gives the following output of myList1:

printing list
[37L, 30L, 142L, 11L, 82L, 143L, 119L, 203L, 154L, 146L, 188L, 156L, 24L, 72L, 9L, 210L, 53420L, 199L, 183L, 200L, 64L, 5L, 77L, 127L, 28L, 12527L, 101L, 159L, 39L, 33203L, 161L, 42L, 197L, 208L, 187L, 17081L, 98L, 148L, 8511L, 196L, 107L, 14614L, 209L, 73L, 87L, 138L, 145L, 31L, 171L, 212L, 61L, 163L, 16L, 5512L, 158L, 110L, 133L, 124L, 100L, 76L, 204L, 84L, 69L, 150L, 202L, 139L, 192L, 5298L, 129L, 45L, 108L, 147L, 170L, 21L, 67L, 30583L, 7427L, 165L, 4762L, 56L, 29L, 26L, 44L, 181L, 11413L, 166L, 79L, 113L, 169L, 123L, 106L, 213L, 121L, 7L, 33190L, 174L, 94L, 33L, 126L, 17245L, 90L, 167L, 201L, 155L, 38L, 63L, 109L, 71L, 18L, 214L, 132L, 164L, 60L, 50L, 194L, 5280L, 103L, 62L, 8080L, 80L, 180L, 191L, 17000L, 120L, 35L, 178L, 78L, 173L, 86L, 43L, 96L, 14927L, 125L, 10L, 134L, 51L, 49L, 55L, 122L, 95L, 17087L, 207L, 26394L, 89L, 141L, 36L, 168L, 193L, 12L, 65L, 136L, 91L, 179L, 53L, 152L, 131L, 144L, 117L, 116L, 105L, 130L, 149L, 162L, 1611L, 118L, 22L, 114L, 7974L, 15896L, 189L, 172L, 182L, 59L, 88L, 27L, 75L, 13L, 2L, 92L, 14L, 57L, 195L, 32L, 215L, 46L, 112L, 17L, 52L, 74L, 70L, 4L, 54L, 1L, 20L, 83L, 186L, 81L, 19L, 140L, 2629L, 160L, 93L, 85L, 1958L, 102L, 176L, 211L, 184L, 41L, 66L, 3L, 135L, 137L, 205L, 25L, 104L, 8L, 157L, 185L, 47L, 206L, 34L, 8048L, 48L, 111L, 151L, 6L, 99L, 97L, 23L, 190L, 68L, 153L, 115L, 177L, 128L, 40L, 175L, 15L, 15579L, 58L, 198L]


And printing account gives the following:

printing account
15
printing account
15579
printing account
58
printing account
198
printing account
[0L]

Answer

Example

>>> l = [[i] for i in range(10)]
>>> l
[[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]]
>>> j = list(l)
>>> j
[[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]]
>>> j[0].append(343)
>>> j
[[0, 343], [1], [2], [3], [4], [5], [6], [7], [8], [9]]
>>> l
[[0, 343], [1], [2], [3], [4], [5], [6], [7], [8], [9]]
>>>

Notice what happens when you append something to the nested list in j? It is also appended to l.

Explain

How does this manifest in your code? It happens here:

myList2[index].append(myList1[account])

If we look at the first time the program loops, index was zero, and you are in the first iteration of the inner loop, then myList2[0] == myList1[0] == items, according to the example we saw above.

So you are actually doing this:

items.append(myList1[account])

What this does it to append the list from myList1[account] to the last position in the items array. Thus when you print that position, you encounter an array rather than a value. This also means that you get an exception after printing the first list that was appended to items thus causing the program to crash.

Solution

There are many ways to fix this for your code, but the easiest will be to create myList2 the same way you created myList1.

myList1 = [[] for _ in range(accountMax+1)]
myList2 = [[] for _ in range(accountMax+1)]

Or

myList2 = [x[:] for x in myList1]

This way, they are both created separate from each other


Better example

To help explain my point about the crash, here is a program that does the same thing as what the OP has:

>>> l = [[i] for i in range(10)]
>>> j = list(l)
>>> index = 0
>>> for items in l:
...     print ('printing list')
...     print (items)
...     for account in items:
...         print ('printing account')
...         print (account)
...         j[index].append(l[account])
...     index = index + 1
... 
printing list
[0]
printing account
0
printing account
[0, [...]]
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
TypeError: list indices must be integers, not list
>>> 
Comments