Create a matrix in Python with sequences increasing - python

I am working on a project and I need to be able to create a function that takes in a value (n) and returns a matrix with increasing values.
ex: Given x = 2, return = [[1],[1, 2]]
Given x = 5, return = [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4],[1, 2, 3, 4, 5]]
Below is what I have thus far:
def matrixIncrease(n):
lst = []
for i in range(n):
lst.append([])
for j in range(0, n):
lst[i].append(j)
return lst
print(matrixIncrease(3))
This will just return
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]
So it looks like the correct amount of inner list are being created. But, the values inside the list are not increasing correctly. Any suggestions?

Maybe you could try this List Comprehension way:
It's quite self-explnatory in the code, just play/experiment with different i and j to see the effects of changes...
Basically the j is to iterate and increase the numbers in each loop.
def create_sub(n):
''' create n sub_lists: each list has increasing items:
[1], [1, 2], [1, 2, 3], .... [1, ... n] '''
sub_matrix = [[j +1 for j in range(0, i)] # j - for col values
for i in range(1, n + 1)] # i - control rows
return sub_matrix
>>>create_sub(5)
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
>>>create_sub(8)
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 5, 6, 7, 8]]

You could try this:
all_ = []
def matrixIncrease(n):
if n == 1:
all_.append([1])
return[1]
j=[]
for i in range(1,n+1):
j.append(i)
matrixIncrease(n-1)
all_.append(j)
matrixIncrease(7)
print(all_)

Related

recursively split list into sub lists based on first element length

I am breaking my head around this small issue which I am sure can (and should) be solved recursively.
# split list in sublists based on length of first element.
list = [3, 1, 2, 3, 4, 1, 2, 3, 4]
#* #*
# *number of elements of the sublist
It is better shown than explained, the above should result to:
[[1, 2, 3], [1, 2, 3, 4]]
The lists I am processing always respect this logic, the first element is always the length of the following n elements.
EDIT:
Based on some of the suggestions, I simply added a yield to get it done lazily.
def split(ls):
"""
func that given a list extracts sub lists with the length indicated by the first element
[2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4] => [[1, 2], [1, 2, 3], [1, 2, 3, 4]]
"""
res = []
while ls:
dim = ls[0]
yield ls[1:dim + 1]
ls = ls[dim + 1:]
return res
>>> list(split([2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4]))
[[1, 2], [1, 2, 3], [1, 2, 3, 4]]
Simple slicing will do:
>>> a = [3, 1, 2, 3, 4, 1, 2, 3, 4]
>>> c = []
>>> while len(a) :
... b = a[0]
... c.append( a[1:b+1] )
... a = a[b+1:]
...
>>> c
[[1, 2, 3], [1, 2, 3, 4]]
Here is a way to achieve what you want:
numbers = [3, 1, 2, 3, 4, 1, 2, 3, 4]
result = []
def split_list(list_):
first = list_.pop(0)
result.append(list_[:first])
if len(list_[first:]) > 0:
split_list(list_[first:])
split_list(numbers)
print(result)
You can use itertools.islice here.
>>> from itertools import islice
>>> lst = [3, 1, 2, 3, 4, 1, 2, 3, 4]
>>> def chunks(lst):
... t=iter(lst)
... c=next(t,None)
... while c:
... yield list(islice(t,None,c))
... c=next(t,None)
...
>>> list(chunks(lst))
[[1, 2, 3], [1, 2, 3, 4]]
I've edited my answer as inspired by someone else's in this thread. This doesn't consume the original array and uses recursion instead of looping.
numbers = [3, 1, 2, 3, 4, 1, 2, 3, 4, 3,1,1,1,1]
def do_take(numbers: []):
result = []
to_take = numbers[0]
result.append(numbers[1:to_take + 1])
if len(numbers) > to_take:
result.append(do_take(numbers[to_take + 1:]))
return result
print(do_take(numbers))
print(numbers)
Results in the following output:
# python /tmp/breakup.py
[[1, 2, 3], [[1, 2, 3, 4], [[1, 1, 1], [[]]]]]
[3, 1, 2, 3, 4, 1, 2, 3, 4, 3, 1, 1, 1, 1]

generate all k-Permutations from n+1 without recalculate the k-permutations from n python 3

My task is to calculate the k-permutations from the updated List by new element
without recalculating the k-permutations already gotten from the previous state of the list. Example:
liste = [1, 2, 3]
3-permutations are:
[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]
The updated list:
liste = [1, 2, 3, 4]
I would like to obtain directly 3-permutations[1, 2, 3, 4]-3-permutations[1, 2, 3]
without recalculating 3-permutations[1, 2, 3]
Calculate directly the new permutations:
[1, 2, 4], [1, 3, 4], [1, 4, 2], [1, 4, 3], [2, 1, 4], [2, 3, 4], [2, 4, 1],
[2, 4, 3], [3, 1, 4], [3, 2, 4], [3, 4, 1], [3, 4, 2], [4, 1, 2], [4, 1, 3],
[4, 2, 1], [4, 2, 3], [4, 3, 1], [4, 3, 2]
Thanks
Computing first the cartesian product {0,1,2,3}x{0,1,2}x{0,1} and taking the nth element of list (1,2,3,4).
r=[]
for prd in itertools.product([[0,1,2,3],[0,1,2],[0,1]]):
l=[1,2,3,4]
r0=[]
for i in prd:
r0 += l[i]
del l[i]
r += r0
EDIT: original answer gives the 3-permutations of [1,2,3,4]
following command answers specifically to question, see how it can be generalized
[list(j) for i in itertools.combinations([1,2,3],2) for j in itertools.permutations(list(i)+[4])]
next case, maybe one of ?
[list(j) for i in itertools.combinations([1,2,3],2) for j in itertools.permutations(list(i)+[4,5])]
[list(j) for i in itertools.combinations([1,2,3,4],3) for j in itertools.permutations(list(i)+[4,5])]
try saving the existing permutations to a list, then do:
if newPermutation not in listOfExistingPermutations:
listOfExistingPermutations.append(newPermutation)
or something along those lines

numpy. Sum multidimensional array at specific indexes

I'm trying to replace something like this code, for a vectorized efficient operation using numpy.
counter = 0
idxs = [1, 3]
lists = [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
for l in lists:
for idx in idxs:
counter += l[idx]
Just sum the array:
idxs = [1, 3]
lists = [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
ary = np.array(lists)
counter = ary[:,idxs].sum()

Count odds in list of lists

What would be the shortest way to count the number of odd numbers in a list of lists like this with arbitrary dimensions, not necessarily 5x5:
list_of_lists = [[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5]]
I tried, but i'd guess there's shorter:
counter = 0
for row in list_of_lists:
for i in row:
if i % 2 != 0:
counter += 1
print(counter)
If you always have one level of flat lists inside the main list you can use an inner loop to flatten, summing the result of each i % 2 which will be 1 for odd and 0 for even numbers:
list_of_lists = [[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5]]
print(sum(i % 2 for sub in list_of_lists for i in sub))
Or use itertools.chain to do the flattening:
from itertools import chain
print(sum(i % 2 for i in chain(*list_of_lists)))
If you had arbitrary nesting, recursion would be an easy way to approach the problem:
def flat(lst):
for i in lst:
if isinstance(i, list):
for j in flat(i):
yield j % 2
else:
yield i % 2
print(sum(flat(list_of_lists)))
The numpy way of counting for a contrast:
import numpy as np
list_of_lists = [[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5]]
l = np.array(list_of_lists)
print len(l[l%2!=0])
l[l%2!=0] returns all the elements that satisfy the condition l%2!=0 and len() counts it.
PS : This of course assumes that the list_of_lists is rectangular. For a solution that allows different length for each inner-list, see Padraic's answer.

Mapping list - list as dictionary in python

Not to be confused with this question in Stackoverflow.
I have a list called a = [2, 3, 4, 1]
I have some function say func(), which is as follows:
def func(a):
o = []
n = len(a)
for i in range(n):
x=a[:]
x[i],x[(i+1)%n] = x[(i+1)%n],x[i]
o.append(x)
return o
and func(a) produces another list as follows:
[[3, 2, 4, 1], [2, 4, 3, 1], [2, 3, 1, 4], [1, 3, 4, 2]]
Now I want to map the output list to the list from which it is generated. So, how to generate a dictionary in the following format:
a : o
key : value1, value2........last value
[2, 3, 4, 1] : [3, 2, 4, 1], [2, 4, 3, 1], [2, 3, 1, 4], [1, 3, 4, 2]
Keys in a dictionary cannot be mutable type. You can have a tuple instead. That is
(2, 3, 4, 1) : [3, 2, 4, 1], [2, 4, 3, 1], [2, 3, 1, 4], [1, 3, 4, 2]
This can be done as
def func(a):
o = []
n = len(a)
for i in range(n):
x=a[:]
x[i],x[(i+1)%n] = x[(i+1)%n],x[i]
o.append(x)
return {tuple(a):o}
For example func([2,3,4,1]) will now return
{(2, 3, 4, 1): [[3, 2, 4, 1], [2, 4, 3, 1], [2, 3, 1, 4], [1, 3, 4, 2]]}
Also note: according to documentation :
The only types of values not acceptable as keys are values containing
lists or dictionaries or other mutable types that are compared by
value rather than by object identity, the reason being that the
efficient implementation of dictionaries requires a key’s hash value
to remain constant
POST COMMENT EDIT
You can access the keys directly usin [] notation.
E.g:
l = [2,3,4,1]
a = func(l)
print (a[tuple(l)])
This will print the list of values.
Or you can loop through the entire dictionary
for i in a.items():
for j in i:
print (j)
This will print
[3, 2, 4, 1]
[2, 4, 3, 1]
[2, 3, 1, 4]
[1, 3, 4, 2]

Categories

Resources