list comprehensions with break - python

I have the following code that I would like to write in one line with a list comprehension.
list1 = [4, 5, 6, 9, 10, 16, 21, 23, 25, 27]
list2 = [1, 3, 5, 7, 8, 11, 12, 13, 14, 15, 17, 20, 24, 26, 56]
list3 = []
for i in list1:
for j in list2:
if j>i:
# print(i,j)
list3.append(j)
break
print(list1)
print(list3)
The output is:
[4, 5, 6, 9, 10, 16, 21, 23, 25, 27]
[5, 7, 7, 11, 11, 17, 24, 24, 26, 56]
It's the break statement that throws me off, I don't know where to put it.
Thank you

To build the expression it helps to ignore the break condition at first:
In [32]: [[j for j in list2 if j > i] for i in list1]
Out[32]:
[[5, 7, 8, 11, 12, 13, 14, 15, 17, 20, 24, 26, 56],
[7, 8, 11, 12, 13, 14, 15, 17, 20, 24, 26, 56],
[7, 8, 11, 12, 13, 14, 15, 17, 20, 24, 26, 56],
[11, 12, 13, 14, 15, 17, 20, 24, 26, 56],
[11, 12, 13, 14, 15, 17, 20, 24, 26, 56],
[17, 20, 24, 26, 56],
[24, 26, 56],
[24, 26, 56],
[26, 56],
[56]]
From there you can add the min constraint:
In [33]: [min([j for j in list2 if j > i]) for i in list1]
Out[33]: [5, 7, 7, 11, 11, 17, 24, 24, 26, 56]

You can't really break a list comprehension's internal for loop, what you can do is avoid having to break it at all by using the next function to find the first occurrence of a matching value:
list1 = [4, 5, 6, 9, 10, 16, 21, 23, 25, 27]
list2 = [1, 3, 5, 7, 8, 11, 12, 13, 14, 15, 17, 20, 24, 26, 56]
list3 = [ next(j for j in list2 if j>i) for i in list1 ]
output:
print(list1)
print(list3)
[4, 5, 6, 9, 10, 16, 21, 23, 25, 27]
[5, 7, 7, 11, 11, 17, 24, 24, 26, 56]
If you are concerned about performance (since the list comprehension will be slower than the loops), you could use a bisecting search in list 2 to find the next higher value:
from bisect import bisect_left
list3 = [ list2[bisect_left(list2,i+1)] for i in list1 ]
This assumes that list2 is sorted in ascending order and that max(list2) > max(list1)

I have tried timing the answer posted by AbbeGijly.
It turns out that it is slower than the original solution. Check it out.
import timeit
print(timeit.timeit('''
list1 = [4, 5, 6, 9, 10, 16, 21, 23, 25, 27]
list2 = [1, 3, 5, 7, 8, 11, 12, 13, 14, 15, 17, 20, 24, 26, 40, 56]
list3 = []
for i in list1:
for j in list2:
if j>i:
# print(i,j)
list3.append(j)
break
'''))
print(timeit.timeit('''
list1 = [4, 5, 6, 9, 10, 16, 21, 23, 25, 27]
list2 = [1, 3, 5, 7, 8, 11, 12, 13, 14, 15, 17, 20, 24, 26, 40, 56]
list4 = [[j for j in list2 if j > i] for i in list1]
'''))
The output is:
3.6144596
8.731578200000001

You could move the break logic into a separate function, then put that function inside a list comprehension:
def smallest_value_larger_than_i(candidate_values, i):
for value in candidate_values:
if value > i:
return value
return None # Not sure how you want to handle this case
list3 = [smallest_value_larger_than_i(list2, i) for i in list1]
This runs slightly slower than your original solution, but if the goal of using a list comprehension is speed, you'll get much better results by improving the algorithm instead. For example, if both lists are sorted, then you can discard elements from list2 as soon as you skip over them once, instead of checking them against the rest of list1. You could also do a binary search of list2 instead of scanning through it linearly.

Related

Slicing Python Lists by Number [duplicate]

This question already has answers here:
Understanding slicing
(38 answers)
Closed 2 years ago.
I am new to Python, is there any best way to resolve below issue list slicing
I have main list called
result = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
I would like to slice above list divide 12 and expecting to have the following output:
new_result = {
'One' : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
'Two' : [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
'Three' : [25, 26]
}
You can do something like this:
result = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
chunk_size = 12
splitted_result = [result[x:x+chunk_size]
for x in range(0, len(result), chunk_size)]
for chunk in splitted_result:
print(chunk)
Result:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
[25, 26]
Into the last for loop you can create the object with the correct keys.
The script logic is simple:
The range function takes three arguments:
start (0)
stop (length of the list)
step (increment between each returned value)
In your case you will have:
range(0, len(result), chunk_size)=[0,12,24]
and you just have to split the initial list in chunks that goes from:
result[0:0+12]
result[12:12+12]
result[24:24+12]
You can do the following:
result = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
new_list = [result[n-1:n+11] for n in result[::12]]
new_result = {}
for n in range(1,len(new_list)+1):
new_result[n] = new_list[n-1]
new_result
{1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
2: [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
3: [25, 26]}
The new_list is just the list with the sliced lists. Then, I convert it into a dictionary called new_result, starting from '1' onwards

Find the first element in a list where all subsequent values increment by one

I would like to find the value in a list, after which all other values increase by 1 only.
# Input
my_list1 = [2, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
my_list2 = [6, 7, 9, 11, 12, 14, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28]
my_list3 = [5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25]
# Output
my_list1 = 15
my_list2 = 20
my_list3 = 18
I was thinking about looping backwards through the lists and when the decrease is larger than 1, extract the value at this position.
for x in reversed(my_list1):
if x decrease > 1:
print(x)
Here's an itertools based one, useful if we have a very long list, so we don't have load it into memory. Here dropwhile will drop values from the iterable while the condition holds, we only need to take the next element in the resulting iterable. Note that next has a default argument, which we can just set to None to avoid having the StopIteration error being raised:
from itertools import tee, dropwhile
def first_diff(it):
i, j = tee(reversed(it), 2)
next(j)
return next((dropwhile(lambda e: e==(next(j)+1), i)), None)
first_diff(my_list1)
# 15
first_diff(my_list2)
# 20
first_diff(my_list3)
# 18
You could zip() the reversed() lists into pairs, then use next() to get the first pair where the difference is greater than 1. We can then unpack the first item from the result.
def first_diff_pair(lst):
return next(
(fst for fst, snd in zip(reversed(lst), reversed(lst[:-1])) if fst - snd > 1),
None,
)
To avoid next() returning StopIteration when no result is found and the iterator is exhausted, we can set the default value to None.
Output:
>>> first_diff_pair([2, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24])
15
>>> first_diff_pair([6, 7, 9, 11, 12, 14, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28])
20
>>> first_diff_pair([5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25])
18
There are several possibilities with list comprehensions. Here I collect every number that increased by more then one, store them in a list and show the last one:
print([my_list1[i+1] for i in range(len(my_list1)-1) if my_list1[i+1] - my_list1[i] > 1][-1])
print([my_list2[i+1] for i in range(len(my_list2)-1) if my_list2[i+1] - my_list2[i] > 1][-1])
print([my_list3[i+1] for i in range(len(my_list3)-1) if my_list3[i+1] - my_list3[i] > 1][-1])
Well, I tried this, and it worked, but there maybe better and more efficient solutions to it too,
l = len(my_list1) - 1
for x in reversed(my_list1):
if my_list1[l] - my_list1[l - 1] == 1:
l -= 1
continue
else:
print(x)
break
Here is a basic loop-based implementation.
def get_first_diff(my_list):
reversed_iter = reversed(my_list)
last = next(reversed_iter)
for v in reversed_iter:
if last - v != 1:
return last
last = v
return None
This is a solution with no duplicate code:
my_list1 = [2, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
my_list2 = [6, 7, 9, 11, 12, 14, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28]
my_list3 = [5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25]
def getIncreaseStartPoint(nums):
i = len(nums) - 1
while (nums[i] - nums[i - 1] == 1):
i -= 1
if (i == 0):
return nums[0]
return nums[i]
print("mylist_1 =", getIncreaseStartPoint(my_list1))
print("mylist_2 =", getIncreaseStartPoint(my_list2))
print("mylist_3 =", getIncreaseStartPoint(my_list3))
Here is my attempt:
my_list1 = [2, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
tmplist = [x - i for i, x in enumerate(my_list1)]
first = my_list1[tmplist.index(tmplist[-1])]
# result 15
How it works:
# tmplist is [2, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6]
Repeating numbers show places of increasing sequences (by +1) in the original list. Last item (tmplist[-1]) is 6, we want to get the position of the first such item (tmplist.index(...)), because there the sequence starts. Finally we look up the value at that index (my_list1[...])
Similar to the Splitting list based on missing numbers in a sequence, you can use itertools.groupby to group consecutive runs of numbers, and from there to get the first value of the last run:
from itertools import groupby
my_list = [2, 5, 7,8,9,10,11,12,13, 15,16,17,18,19,20,21,22,23,24]
first_value = None
for _, group in groupby(enumerate(my_list), lambda x: x[1] - x[0]):
first_value = next(group)[1]
print(first_value)
# 15

Not sure of what is wrong, trying to produce a 5x5 grid python 1-25

I am not sure what I am doing wrong, if anyone can see exactly, please inform me.
Tried:
grid = [[n in range(1,6)*5]]
and
grid [[]*5 for n in range(1,25)]
My code:
grid = [[x for x in range(1,25)] for y in range(5)]
Output:
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]]
Desired:
[[1,2,3,4,5], [6,7,8,9,10], [11,12,13,14,15],[16,17,18,19,20],[21,22,23,24,25]]
It's fairly obvious that values in inner lists have to be related both to internal counter in each list (x) and position of list in outer list (y). Your code fails to take care about second requirement.
grid = [[1+x+5*y for x in range(5)] for y in range(5)]
You are iterating in a range from 1 to 24(inclusive) in your inner loop, which is why your lists are too long, and have the same values in them.
You somehow need to make the variable of your outer loop dictate the inner loop so each range within the inner loop start from a different point. Also, calibrating the length of the inner range is essential.
That being said, I suggest the following to get your desired output.
grid = [list(range(i, i+5)) for i in range(1, 26, 5)]
You can cut a list into sublist of 5, see this code
data=range(1,26)
len_sublist = 5
print [data[x:x+len_sublist] for x in xrange(0, len(data), len_sublist)]

Finding craters [descending/ ascending ints] in a python list of ints

I have a list of ints in python, and I would like the output to be a list of different "craters" in the sequence. I define a crater as a sequence of numbers that begins with descending ints that gradually grow bigger, until they reach a number that is equal to the first int of the crater or greater than the first int in the crater.
If the last number is equal or smaller than the first - it should be in the output at the end of the crater. If the last number is greater than the first number in the crater - it should not be appended to the end of the output list.
For example, for the list:
1,2,3,4,5,6,5,4,3,4,5,6,7,8,9
A "crater" would be:
6,5,4,3,4,5,6
My code:
def find_crater(my_list):
cur_crater = []
for i in range(len(my_list)-1):
#check if the numbers are decreasing
if (my_list[i] - my_list[i+1] > 0):
cur_crater.append(my_list[i])
#if increasing - check if we're in a crater
#and if current number is smaller than begining of crater
elif len(cur_crater) > 1 and my_list[i] <= cur_crater[0]:
cur_crater.append(my_list[i])
#print crater and empty list
elif len(cur_crater) > 1 and my_list[i+1] > cur_crater[0]:
print(cur_crater)
cur_crater = []
#continue if we're out of a crater
else:
continue
#catching the last crater in the list
if len(cur_crater) > 1:
#include last int
if my_list[i] - my_list[-1] < 0 and my_list[-1] <= cur_crater[0]:
cur_crater.append(my_list[-1])
print(cur_crater)
return
I have called the function on 2 lists. The 1st output is as expected:
ok_list = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23,
24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14,
17, 27, 28, 19, 17, 19, 21, 19, 12, 23, 25, 27]
Ok list output [edit: not so ok - it ommited the first '4' so turns out it's not so OK after all]:
[12, 7, 4, 2, 4, 5, 6, 5, 12]
[26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17]
[28, 19, 17, 19, 21, 19, 12, 23, 25, 27]
However, the second list combines 2 lists of craters into 1 list in the output:
problematic = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23,
24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14,
17, 27, 19, 25, 19, 12, 23, 25, 27]
problematic Output:
[12, 7, 4, 2, 4, 5, 6, 5, 12]
[26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17, 27, 19, 25, 19, 12, 23, 25]
I was expecting:
[12, 4, 7, 4, 2, 4, 5, 6, 5, 12]
[26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17]
[27, 19, 25, 19, 12, 23, 25, 27]
I tried to take care of this by writing:
my_list[i+1] > cur_crater[0]
and thus checking the size of next int in the list - but that does not seem to fix it [I left it in the code even though it does not do the trick in hopes of someone explaining why is that wrong/ not working?].
In conclusion, my code can't handle it when there is a crater right after a crater with only one int in between.
If the input is:
[12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 10, 9, 8, 6, 9, 10]
Then the output is one long list, but I'd like to split it after list item 12 and before list item 21, but the output is one long list.
I would love to get info about any library or method that can give me more ideas regarding a better and more efficient solution.
Presuming your expected output is wrong which it seems to be, all you want to do is go until you find an element >= to the start of the chain and catch chains that only contain a single element:
def craters(lst):
it = iter(lst)
# get start of first chain
first = next(it)
tmp = [first]
# iterate over the remaining
for ele in it:
# >= ends chain
if ele >= first:
# if equal, add it and call
# next(it) to set the next first element.
if ele == first:
tmp.append(ele)
yield tmp
first = next(it)
tmp = [first]
# else yield the group if it has > 1 element.
# if it has 1 element it is not a descending start sequecne
else:
if len(tmp) > 1:
yield tmp
tmp = [ele]
first = ele
else:
tmp.append(ele)
if len(tmp) > 1: # catch single element last
yield tmp
Output:
In [5]: ok_list = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23,
...: 24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14,
...: 17, 27, 28, 19, 17, 19, 21, 19, 12, 23, 25, 27]
In [6]: problematic = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23,
...: 24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14,
...: 17, 27, 19, 25, 19, 12, 23, 25, 27]
In [7]: ex_ok = [[12, 4, 7, 4, 2, 4, 5, 6, 5, 12],
...: [26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17],
...: [28, 19, 17, 19, 21, 19, 12, 23, 25, 27]]
In [8]: ex_p = [[12,4, 7, 4, 2, 4, 5, 6, 5, 12],
...: [26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17],
...: [27, 19, 25, 19, 12, 23, 25, 27]]
In [9]: print(list(craters(problematic)) == ex_p)
True
In [10]: print(list(craters(ok_list)) == ex_ok)
True
In [11]: print(list(craters([12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 10, 9, 8, 6, 9, 10])))
[[12, 4, 7, 4, 2, 4, 5, 6, 5, 12], [21, 10, 9, 8, 6, 9, 10]]
In [12]: list(craters([1, 2, 3, 4, 5, 6, 5, 4, 3, 4, 5, 6, 7, 8, 9]))
Out[13]: [[6, 5, 4, 3, 4, 5, 6]]
That does not involve any slicing/indexing you can lazily return each group.
To simplify your algorithm, the steps are:
Start with the first element, then check if the next element is >=, if it is and it is equal add it to the group, if it is > set that to be the new start of the group.
If the new first is not greater than the next element the length of that group will be one as it does not satisfy sequence of numbers that begins with descending. So we keep consuming and setting the next element to be the first element of the sequence until we find one the is > the next element, that is what the call to next(it) is doing then we just need to wash and repeat.
Here is what I came with:
def find_crater(my_list):
previous = None
current_crater = []
crater_list = []
for elem in my_list:
#For the first element
if not previous:
previous = elem
continue
if len(current_crater) == 0:
if elem > previous:
previous = elem
else:
current_crater.append(previous)
previous = elem
else:
if elem > current_crater[0]:
current_crater.append(previous)
crater_list.append(current_crater)
current_crater = []
previous = elem
else:
current_crater.append(previous)
previous = elem
if len(current_crater) != 0:
if elem > current_crater[0]:
current_crater.append(previous)
crater_list.append(current_crater)
else:
current_crater.append(previous)
crater_list.append(current_crater)
return crater_list
That gave me the exact output you want:
In [5]: ok_list = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23,
...: 24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14,
...: 17, 27, 28, 19, 17, 19, 21, 19, 12, 23, 25, 27]
In [6]: find_crater(ok_list)
Out[6]:
[[12, 4, 7, 4, 2, 4, 5, 6, 5, 12],
[26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17],
[28, 19, 17, 19, 21, 19, 12, 23, 25, 27]]
In [7]: problematic = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23,
...: 24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14,
...: 17, 27, 19, 25, 19, 12, 23, 25, 27]
In [8]: find_crater(problematic)
Out[8]:
[[12, 4, 7, 4, 2, 4, 5, 6, 5, 12],
[26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17],
[27, 19, 25, 19, 12, 23, 25, 27]]
Try this:
We just slice the list finding start_index:end_index making three cases
When element is equal
When element is greater
Boundary case when last element even if smaller may need to be sliced
def find_crater(l):
result = []
start_index = 0
for i in range( start_index +1,len(l)):
start = l[start_index]
if i==len(l)-1 and l[i]!=start:
result = l[start_index:i+1]
print result
elif l[i]==start:
end_index = i+1
result = l[start_index:end_index]
start_index = end_index +1
if len(result)>1:
print result
elif l[i]>start:
end_index = i
result = l[start_index:end_index]
start_index = end_index
if len(result)>1:
print result
Input:
ok_list = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23,
24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14,
17, 27, 28, 19, 17, 19, 21, 19, 12, 23, 25, 27]
problematic = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23,
24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14,
17, 27, 19, 25, 19, 12, 23, 25, 27]
Output:
find_crater(ok_list)
find_crater(problematic)
[12, 4, 7, 4, 2, 4, 5, 6, 5, 12]
[25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17]
[28, 19, 17, 19, 21, 19, 12, 23, 25, 27]
[12, 4, 7, 4, 2, 4, 5, 6, 5, 12]
[25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17]
[27, 19, 25, 19, 12, 23, 25, 27]

Why am I getting "list assignment index out of range" error?

I keep getting the same error:
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
IndexError: list assignment index out of range
What's wrong with the following code?
myList = [([None] * 8) for x in range(16)]
for i in range(0,7):
for j in range(0,15):
myList[i][j] = 2 * i
The list comprehension
myList = [([None] * 8) for x in range(16)]
can be understood like this
mylist = []
for x in range(16):
mylist.append([None] * 8)
So, you are creating a list of 16 lists, each contains 8 Nones. But with the loops
for i in range(0,7):
for j in range(0,15):
you are trying to access 15 elements from the first 7 lists. That is why it is failing. Instead, you might want to do
for i in range(16):
for j in range(8):
...
Actually you can do the same in list comprehension, like this
[[2 * i for j in range(8)] for i in range(16)]
Demo:
>>> from pprint import pprint
>>> pprint([[2 * i for j in range(8)] for i in range(16)])
[[0, 0, 0, 0, 0, 0, 0, 0],
[2, 2, 2, 2, 2, 2, 2, 2],
[4, 4, 4, 4, 4, 4, 4, 4],
[6, 6, 6, 6, 6, 6, 6, 6],
[8, 8, 8, 8, 8, 8, 8, 8],
[10, 10, 10, 10, 10, 10, 10, 10],
[12, 12, 12, 12, 12, 12, 12, 12],
[14, 14, 14, 14, 14, 14, 14, 14],
[16, 16, 16, 16, 16, 16, 16, 16],
[18, 18, 18, 18, 18, 18, 18, 18],
[20, 20, 20, 20, 20, 20, 20, 20],
[22, 22, 22, 22, 22, 22, 22, 22],
[24, 24, 24, 24, 24, 24, 24, 24],
[26, 26, 26, 26, 26, 26, 26, 26],
[28, 28, 28, 28, 28, 28, 28, 28],
[30, 30, 30, 30, 30, 30, 30, 30]]
Note: I have used 16 and 8 in the range function because it, by default, starts from 0 and iterates till the parameter passed to it - 1. So, 0 to 15 and 0 to 8 respectively.
You have your indices reversed; the outer list has 16 elements, but you are trying to index the inner list past the 8 elements that are there.
That's because your list comprehension built 16 lists of each 8 values, so len(myList) is 16, and len(myList[0]) is 8.
Reverse the ranges:
for i in range(15):
for j in range(7):
myList[i][j] = 2 * i
or reverse the use of i and j when trying to index against myList:
for i in range(7):
for j in range(15):
myList[j][i] = 2 * i
Note that the outer myList is using j now and each nested inner list is indexed with i.
Both i and j omit the last element, if that wasn't intentional, use 8 and 16 rather than 7 and 15.

Categories