5

I have a 2D list of 416 rows, each row having 4 columns. Rows 1-4 contain their row number 4 times (i.e., [...[1,1,1,1],[2,2,2,2]...]. Row 330 contains [41,22,13,13]. Everything else is [0,0,0,0]. Currently I am using a for loop with many explicit if statements.

myList = [[0,0,0,0]]
for i in range(1, 416):
    if i == 1 or i == 2 or i == 3 or i == 4:
        myList.append([i,i,i,i])
    elif i == 330:
        myList.append([41,22,13,13])
    else:
        myList.append([0,0,0,0])

What is a more efficient way for me to define this array?

The other questions I have seen on SO don't seem to explicitly address this question, but if someone finds one that can be considered a duplicate please mark this question as such and I will accept it.

4
  • does this have to be a list or are other formats ok? Commented Jul 12, 2017 at 14:45
  • I'd prefer list. But! The main thing I care about is the end result, so if you know of another, better method, lay it on me. Commented Jul 12, 2017 at 14:46
  • 2
    Have you looked at numpy arrays? Much like @Moses's answer, I'd start with a np.zeros and then adjust the necessary rows. Commented Jul 12, 2017 at 14:51
  • I do know (and love) numpy, but I have encountered more than one instance where I have a task or assignment that does not permit the use of numpy. In addition, I am a big fan of improving one's use of the simpler tools before going to more advanced ones. So I suppose their is a CS Theory aspect to this question as well. Commented Jul 12, 2017 at 14:53

2 Answers 2

7

Since the bulk of the list is a sublist of zeros (in array term, sparse), I'll just preallocate and then use slice assignment/indexing to update:

my_list = [[0, 0, 0, 0] for _ in range(416)]
my_list[330] = [41,22,13,13]
my_list[1:5] = [[i]*4 for i in range(1, 5)]

This avoids repeated branch evaluation for a host of false cases and the repeated appends.

OTOH, having zeros all over your memory can be avoided if you actually keep the data structure as a sparse matrix. You could have a look at the SciPy 2-D sparse matrix package.

Sign up to request clarification or add additional context in comments.

8 Comments

Surely the right idea, but the output from their code snippet is not equal to this output (their output may be wrong)
@Chris_Rands I'll say their output is wrong. They are pre-assigning myList = [[]].
If my_list is not going to be modified, you can even say zero_list = [0, 0, 0, 0] and then start with my_list = [zero_list for _ in range(416)], saving the time and memory used in creating unnecessary lists.
@jdehesa Not a good idea. You do a reference copy there, mutating every list just by changing 1.
@CommonSense ikr, that duplicates your sublist across the list and all hell unleashes. It's a bad idea. See what happens when you update one of the sublists.
|
1

Off the top of my head, a really simple and fast way to do it:

import itertools

answer = list(itertools.chain([[i,i,i,i] for i in range(1,5)], [[0,0,0,0] for _ in range(330-6)], [[41,22,13,13]], [[0,0,0,0] for _ in range(416-330)]))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.