Add elements of unknown list length - Python - python-3.x

I seem to be struggling a little with this issue. Let's say you have a list of various lengths i.e:
first_list = [8, 7, 5, 1, 2, 4]
or
second_list = [6, 8, 4, 1]
regardless of how long or short the list is how would you be able to add the elements of each list such that all the elements get added together? I.e First > first + second > first + second + third > ... etc
first_list = [8, 8+7, 8+7+5, 8+7+5+1, 8+7+5+1+2, 8+7+5+1+2+4]
second_list = [6, 6+8, 6+8+4, 6+8+4+1]
I have tried a few different things but just don't seem to be able to do this :-/

Try this:
for i in range(1,len(myList)):
myList[i] += myList[i-1]

You can also use a list comprehension:
>>> my_list = [8, 7, 5, 1, 2, 4]
>>> [sum(my_list[:i+1]) for i in range(len(my_list))]
[8, 15, 20, 21, 23, 27]
Note that even though this looks more compact, #MarkSnyder's answer is actually more performant as it has a time complexity of O(n) while this one is O(n^2).
Edit: If you are using Python 3.8 or higher, you can use the walrus operator to have a list comprehension with O(n) complexity:
>>> my_list = [8, 7, 5, 1, 2, 4]
>>> s = 0
>>> [s := s + i for i in my_list]
[8, 15, 20, 21, 23, 27]

Related

Repetitive sequence (optimization)

I try to solve this problem:
initial list = [0, 1, 2, 2]
You get this sequence of numbers [0, 1, 2, 2] and you need to add every time the next natural number (so 3, 4, 5, etc.) n times, where n is the element of its index. For example, the next number to add is 3, and list[3] is 2, so you append [3] 2 times. New list will be: [0, 1, 2, 2, 3, 3]. Then the index of 4 is 3, so you have to append 4 three times. The list will be [0, 1, 2, 2, 3, 3, 4, 4, 4] and so on. ([0, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10])
In order to solve this, I tried various approaches. I used recursion, but a recursive approach is very slow in this case. I tried as well the mathematical formula from OEIS (A055086) => a(n) = ceiling(2*sqrt(n+1)) - 2. The problem with the formula is that after 2 ** 20 it is too imprecise.
So, my next idea was to use memoization:
lst = [0, 1, 2, 2]
from itertools import repeat
def find(n):
global lst
print(lst[-1], n, flush = True)
if len(lst) > n:
return lst[n]
for number in range(lst[-1]+1, n+1):
lst += list(repeat(number, lst[number]))
if len(lst) > n:
return lst[n]
Now, this approach works until 2 ** 37, but after this is just timing out. The site where I try to implement my algorithm is (https://www.codewars.com/kata/5f134651bc9687000f8022c4/train/python). I don't ask for a solution, but for any hint on how to optimize my code.
I googled some similar problems and I found that in this case, I could use the total sum of the list, but is not very clear to me yet how could this help me.
Any help is welcomed!
You can answer it iteratively like so:
def find(n):
lst = [0,1,2,2]
if n < 4:
return lst[n]
to_add = 3
while n >= len(lst):
for i in range(lst[to_add]):
lst.append(to_add)
to_add += 1
return lst[n]
You could optimise for large n by breaking early in the for loop, and by keeping track of the list length separately, rather than calls to len

How to find missing numbers from list in Python?

lst = [1, 4, 5, 9, 6]
How to write a code to get some missing values which must return [2, 3, 7, 8]?
Here is my code
new_list = []
for i in range(1, len(lst1)):
if i not in lst1:
new_list.append(i)
print(new_list)
You can convert them to sets and use "-" to calculate the difference. Note that the order is important.
You need to define what you want to compare your list to if you want to find the missing elements. You can automatically do this if it is simple like "the numbers from 1 to 10" using the code:
list(range(1, 10))
The comparison code is:
lst1 = [1, 4, 5, 9, 6]
lst2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
out = list(set(lst2) - set(lst1))
print(out)
which returns
[8, 2, 3, 7]
It isn't clear exactly what you want from your question, if you give a more detail it will be easier to help.

Iterate through 2d list and append to multiple other lists

I have a 2-D list:
lst = [[1,2,3,4,5,6,7,8,9],[11,12,13,14,15]]
I want to store 0 to N-1 of each list in the 2-D list in a separate list and 1 to N in another one. So I create two new lists to be appended where they have the same length as the 2-D lst:
alpha, beta = [[]]*len(lst), [[]]*len(lst)
Then I run this code:
for i in range(len(lst)):
for j in range(len(lst[i])-1):
alpha[i].append(lst[i][j])
beta[i].append(lst[i][j+1])
But the for-loops seem to be iterating through all lists every time.
I want to get the result
alpha = [[1,2,3,4,5,6,7,8],[11,12,13,14]]
beta = [[2,3,4,5,6,7,8,9],[12,13,14,15]]
Instead, I am getting
alpha = [[1,2,3,4,5,6,7,8,11,12,13,14],[1,2,3,4,5,6,7,8,11,12,13,14]]
beta = [[2,3,4,5,6,7,8,9,12,13,14,15],[2,3,4,5,6,7,8,9,12,13,14,15]]
There is definitely something wrong with my code and I'm not able to figure it out, any help is appreciated!
I think list comprehensions might make your code more succinct:
alpha = [i[:-1] for i in lst]
beta = [i[1:] for i in lst]
>>> alpha
[[1, 2, 3, 4, 5, 6, 7, 8], [11, 12, 13, 14]]
>>> beta
[[2, 3, 4, 5, 6, 7, 8, 9], [12, 13, 14, 15]]
foo, bar= [], []
for i in range(len(lst)):
for j in range(len(lst[i])-1):
foo.append(lst[i][j])
bar.append(lst[i][j+1])
alpha[i] = foo
beta[i] = bar
foo, bar = [], []

How to use list comprehensions for this?

I want to take input of 2 numbers: the number of rows and the number of columns. I then want to use these to output a matrix numbered sequentially. I want to do this using a list comprehension. The following is a possible output.
>>>> my_matrix = matrix_fill(3, 4)
>>>> my_matrix
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
I am using the following code to output a sequentially numbered list:
def matrix_fill(num_rows, num_col):
list=[i for i in range(num_col)]
return (list)
I cannot, however, figure out how to make the sequential list of numbers break into the separate lists as shown in the output based on num_rows.
I don't think you need itertools for that. The range function can take a step as a parameter. Like this:
def matrix_fill(rows,cols):
return [[x for x in range(1,rows*cols+1)][i:i+cols] for i in range(0,rows*cols,cols)]
And then it works as expected.
>>> matrix_fill(3,4)
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
Let's break this down a little bit and understand what's happening.
>>> [x for x in range(1,3*4+1)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
So what we want to do is to get a new slice every four elements.
>>> [x for x in range(1,3*4+1)][0:4]
[1, 2, 3, 4]
>>> [x for x in range(1,3*4+1)][4:8]
[5, 6, 7, 8]
>>> [x for x in range(1,3*4+1)][8:12]
[9, 10, 11, 12]
So we want to iterate over the elements of the list[x for x in range(1,3*4+1)] of length "rows*cols" ( 3 * 4 ), create a new slice every "cols" number of elements, and group these slices under a single list. Therefore, [[x for x in range(1,rows*cols+1)][i:i+cols] for i in range(0,rows*cols,cols)] is a suitable expression.
Nest a list comprehension inside another one, use itertools.count() to generate the sequence:
import itertools
rows = 3
cols = 4
count_gen = itertools.count() # pass start=1 if you need the sequence to start at 1
my_matrix = [[next(count_gen) for c in range(cols)] for r in range(rows)]
print(my_matrix)
# prints: [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
# As a function
def matrix_fill(rows, cols):
count_gen = itertools.count()
return [[next(count_gen) for c in range(cols)] for r in range(rows)]
If you used the numpy module, the method is extremely simple, with no list comprehension needed.
my_matrix = np.arange(1, 13).reshape(3,4)
Printing the variable my_matrix shows
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]

multiplying elements in a 3x4 matrix individually in python 3 using loops (no numpy)

Im trying to make a matrix that is 3 rows by 4 columns and includes the numbers 1-12. Would then like to multiply those numbers by a factor to make a new matrix.
def matrix(x):
matrix=[[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
new_matrix=[[x*1,x*2,x*3],[x*4,x*5,x*6],[x*7,x*8,x*9],[x*10,x*11,x*12]]
print(new_matrix)
This approach works, however it does not use loops, I'm looking for an approach that uses loops, something like this:
def matrix(x):
for i in range(3):
matrix.append([])
for j in range(4):
matrix[i].append(0)
return matrix
You do not need to use explicit loops for something like this (unless you really want to). List comprehensions are a much more efficient way to generate lists, and have a similar syntax to a for loop:
Here is a comprehension for generating any MxN matrix containing the numbers up to M * N:
def matrix(m, n):
return [[x+1 for x in range(row * n, (row + 1) * n)] for row in range(m)]
Here is a comprehension for multiplying the nested list returned by matrix by some factor:
def mult(mat, fact):
return [[x * fact for x in row] for row in mat]
Here is the result for your specific 3x4 case:
>>> m = matrix(3, 4)
>>> print(m)
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
>>> m2 = mult(m, 2)
>>> print(m2)
[[2, 4, 6, 8], [10, 12, 14, 16], [18, 20, 22, 24]]
If you want the indices to be swapped as in your original example, just swap the inputs m and n:
>>> matrix(4, 3)
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
mult will work the same for any nested list you pass in.

Resources