Inserting elements at a specific index python - python

I'm trying to insert a list of number into a list of list. I've simplified the code just as an example because the actual thing is fairly long. Basically i have two list and the end result i want is as follows:
C = [
[1,1,x],
[2,1,x],
[3,1,x],
[1,2,x],
[2,2,x],
[3,2,x],
[1,3,x],
[2,3,x],
[3,3,x],
]
You can think of this as a matrix of nxn dimensions, but the list has to be like this. Basically my problem is that i can't figure out how to insert the first list into index 0 and 1 like in the matrix above. The second list is just the x's at index 3 which i can work my way around.
Here is what i have so far, any help would be appreciated. Thanks a lot!!
set_I = [1,2,3]
set_J = [x,x,x,x,x,x,x,x,x]
C = []
for i in range(len(set_I)*len(set_I)):
C.append([])
for liste in C:
liste.insert(0,0)
liste.insert(1,0)
liste.insert(2,0)

Super wild guess:
set_I = [1,2,3]
set_J = [20,21,22,23,24,25,26,27,28]
C = []
for i in range(len(set_I)):
for j in range(len(set_I)):
C.append([set_I[j], set_I[i], set_J[3*i+j]])
print(C)
Result:
[
[1, 1, 20],
[2, 1, 21],
[3, 1, 22],
[1, 2, 23],
[2, 2, 24],
[3, 2, 25],
[1, 3, 26],
[2, 3, 27],
[3, 3, 28]
]

I am confused. If you want the product, then use it.product(), like:
set_I = [1,2,3]
set_J = [0,0,0,0,0,0,0,0,0] #Just putting zeros instead of x's.
import itertools as it
[[a,b,c] for (a,b),c in zip(it.product(set_I,repeat=2),set_J)]
If you want to initialize an empty list of list, then simply multiply.
[[0]*3]*9

I guess if you are looking for that problem, then I guess you must use this code
set_I = [1,2,3]
set_J = ['x','x','x','x','x','x','x','x','x']
C = []
for i in range(len(set_I)*len(set_I)):
C.append([])
for i in range(len(set_I)):
for j in range(len(set_I)):
C[3*i+j].append(j+1)
C[3*i+j].append(i+1)
C[3*i+j].append(set_J[3*i+j])

Related

python how to generate combinations from a list of lists

I hope you can help me, I want to generate combinations from the following list of lists (to work as a nxn matrix):
A = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
But I need that if e.g I take the first number of the first list, then as a matrix operation, remove the other elements of the column and the row of the selected element and then generate the possible combinations
For example, I choose the 1 on the first list, then the only possible combinations to generate are: (1,5,9) and (1,8,6) because the elimination the row and column.
I'm trying to build a recursive function to achieve that by removing column and row the problem is that I'm not sure about how to build the list with the combinations.
This is that I have so far:
list = []
def combinations(matrix):
matrix_rows = len(matrix)
if matrix_rows == 0:
# Base case
return matrix
else:
# Recursive case
# Always select first row
seq = []
for index, a in enumerate(matrix[0]):
E = a
seq.append(E)
# Remove i from row of index element a
new_matrix = remove_row(matrix, 0)
# Remove j from column index of element a
new_matrix = remove_column(new_matrix, index)
# Call again with new matrix
combinations(new_matrix)
list.append(seq)
return list
def remove_row(original_matrix, element_row_index):
new_matrix = []
if (len(original_matrix)) >= element_row_index:
new_matrix = original_matrix[:]
new_matrix.remove(original_matrix[element_row_index])
return new_matrix
def remove_column(matrix, index):
return [(x[0:index] + x[index + 1:]) for x in matrix]
With A matrix from above I'll expect to have:
A = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
print("Result: ", combinations(A))
Result: [[1,5,9], [1,6,8], [2,4,9], [2,6,7], [3,4,8], [3,5,7]]
Anyone can help me? Or give me a suggestion for a better approach
Added: An 4x4 example:
A = [[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]]
Results: [1,6,11,16], [1,6,12,15],[1,7,10,16], [1,7,12,14], [1,8,10, 15], [1,8,11, 14], ....
I think this can be done simply and with no recursion at all.
Basically, you want to choose all the possible permutations of range(n) on the rows (or columns) while going through the columns (or rows respectively) in order.
Here's one easy solution:
from itertools import permutations
import numpy as np
n = 3
x = np.arange(n ** 2).reshape((n, n)) + 1 # so as to fit in with your example
perms = permutations(range(n))
combinations = [list(x[range(n), p]) for p in perms]
print(combinations)
>> [[1, 5, 9], [1, 6, 8], [2, 4, 9], [2, 6, 7], [3, 4, 8], [3, 5, 7]]
If, however, you're not using numpy-compatible stuff, but rather a list-of-lists, here's a small tweak on the above that works just as well:
x = [[1, 'A'], [2, 'B']] # a "small" case so it's easy to follow
n = len(x)
index_list = range(n)
perms = permutations(index_list)
combinations = [[x[i][p[i]] for i in index_list] for p in perms]
print(combinations)
>> [[1, 'B'], ['A', 2]]
The above assumes you're still using "square" data. Meaning that the length of each inner list is the same length as the outer list containing them.
Hope that helps and that it does what you meant. If not please comment and I'll correct whatever's needed. I'll leave turning this into a function to the reader ;-)
Good luck!

Loop from a specific point in a list of lists Python

I would like to append to a new list all elements of an existing list of lists after a specific point
m = [[1,2,3],[4,5,10],[6,2,1]]
specific point = m[0][2]
newlist = [3,4,5,10,6,2,1]
You can directly slice off the remainder of the first target list and then add on all subsequent elements, eg:
m = [[1,2,3],[4,5,10],[6,2,1]]
y, x = 0, 2
new_list = m[y][x:] + [v for el in m[y+1:] for v in el]
# [3, 4, 5, 10, 6, 2, 1]
Here's a couple of functional approaches for efficiently iterating over your data.
If sublists are evenly sized, and you know the index from where to begin extracting elements, use chain + islice:
from itertools import chain, islice
n = 3 # Sublist size.
i,j = 0,2
newlist = list(islice(chain.from_iterable(m), i*n + j, None))
If you don't know the size of your sublists in advance, you can use next to discard the first portion of your data.
V = chain.from_iterable(m)
next(v for v in V if v == m[i][j])
newlist = list(V)
newlist.insert(m[i][j], 0)
This assumes there is no identical value earlier in the sequence.
You can put a conditional in your iteration and only add based on that condition. Once you hit that specific index, make your condition true. Something like this:
m = [[1,2,3],[4,5,10],[6,2,1]]
specific_point = (0,2)
newlist = [3,4,5,10,6,2,1]
output = []
for i in range(len(m)):
for j in range(len(m[i])):
if (i,j) < specific_point:
continue
output.append(m[i][j])
output:
[3, 4, 5, 10, 6, 2, 1]
why not flatten the initial list and go from there
flat_list = [item for sublist in m for item in sublist]
would return [1,2,3,4,5,10,6,2,1] so now you're really on flat_list[2:]
Most of the answers only work for this specific shape of nested list, but it's also possible to create a solution that works with any shape of nested list.
def flatten_from(sequence, path=[]):
start = path.pop(0) if path else 0
for item in sequence[start:]:
if isinstance(item, (list, tuple)):
yield from flatten_from(item, path)
else:
yield item
With the example from the question
>>> list(flatten_from([[1, 2, 3], [4, 5, 10], [6, 2, 1]], [0, 2]))
[3, 4, 5, 10, 6, 2, 1]
It also works with any shape and level of nesting of the input data
m = [[1], [[2], [3, 4, 5, 6, 7]], 8, [9, [10, 11]]]
flatten_from(m, [])) # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
flatten_from(m, [2]) # 8, 9, 10, 11
flatten_from(m, [1, 1, 3]) # 6, 7, 8, 9, 10, 11
This is a bit of a bastard algorithm, though. On one hand, it uses nice functional programming concepts: recursion and yield.
On the other hand it relies on the side effect of mutating the path argument with list.pop, so it's not a pure function.
Below solution will work for your case where your array is restricted to list of list and the size of 'sublist' is consistent throughout i.e "3" in your case
m = [[1,2,3],[4,5,10],[6,2,1]] #input 2D array
a, b = 0, 2 #user input --> specific point a and b
flat_list_m = [item for firstlist in m for item in firstlist] #flat the 2D list
print (flat_list_m[len(m[0])*a+b:]) #print from specific position a and b, considering your sublist length is consistent throughout.
I hope this helps! :)

Running through variables in for loop

I'm new to Python, but I use it to process data. I've got a large amount of data stored as float arrays:
data1
data2
data3
I want to run similar processing for each data file. I was thinking of using a for loop:
for i in range(1,4):
I would like to then multiply the three data files by two, but I'm not sure how to continue afterwards. I imagine it would look like his:
for i in range(1,4):
data_i=data_i*2
Thank you.
You could make a two-dimensional array, meaning you put your float arrays inside another array.
Your situation right now would look like this:
data1 = [12, 2, 5]
data2 = [2, 4, 8]
data3 = [3, 0, 1]
By putting your arrays inside another array by doing this:
datax = [data1, data2, data3]
Your new situation would look like this:
datax = [[12, 2, 5], [2, 4, 8], [3, 0, 1]]
Now we can loop over the new datax array and perform an action on it's elements, data1, data2 and data3.
Something along the lines of:
datax = [[12, 2, 5], [2, 4, 8], [3, 0, 1]]
for sub_array in datax:
perform_action(sub_array)
You can simply store the data in e.g. list
data_list = [data1, data2, data3]
for i, data in enumerate(data_list):
some_fancy_stuff
data_list[i] = data * 2
Some explanation - enumerate will literally enumerate the items of the list with index i and also assigns data_list[i] to variable data. Than you can do whatever you want with data and its index i.
You could also use Python comprehension instead of loops, here is an example to illustrate it:
>>> a1 = [1,2,3]
>>> a2 = [4,5,6]
>>> a3 = [7,8,9]
>>> A = [a1, a2, a3]
>>>
>>> print [[x*2 for x in a] for a in A]
[[2, 4, 6], [8, 10, 12], [14, 16, 18]]
>>>
Let me explain it also.
The following construction is called comprehension:
a = [x*2 for x in X]
It produces an array (as you could see the brackets [ ]) of processed values (in the example value multiplication by two) from array X. It's as if we wrote:
a = []
for x in X:
a.append(x*2)
but in more concise way.
In your situation we used two comprehension one in one:
[x*2 for x in a]
and:
[ [....] for a in A]
So it's the same as if we did:
result = []
for a in A:
for x in a:
result.append(x*2)
but in more concise way again.
If you asked about variable names modification, so it is not possible in the Python without altering the language processor. But I guess you don't need it in that task at all.

Rearrange a python list into n lists, by column

I want to rearrange a list l into a list of n lists, where n is the number of columns.
e.g.,
l = [1,2,3,4,5,6,7,8,9,10]
n = 4
==> [[1,5,9],[2,6,10],[3,7][4,8]]
Can someone please help me out with an algorithm? Feel free to use any python awesomeness that's available; I'm sure theres some cool mechanism that's a good fit for this, i just can't think of it.
PS The example list just happened to be ordered numbers starting at 1. That's not my actual scenario.
There is indeed a cool mechanism for this in Python: the three-argument form of slicing, where the last argument is step size.
>>> l = [1,2,3,4,5,6,7,8,9,10]
>>> n = 4
>>> [l[i::n] for i in range(n)]
[[1, 5, 9], [2, 6, 10], [3, 7], [4, 8]]
l = [1,2,3,4,5,6,7,8,9,10]
n = 4
def f(l,n):
A = []
[A.append([]) for i in xrange(n)]
[ A [(i - 1) % n].append(i) for i in l]
return A
print f(l,n)
[[1, 5, 9], [2, 6, 10], [3, 7], [4, 8]]
The following function does what you want to achieve:
def rearrange(seq,n):
return [[v for i,v in enumerate(seq[x:]) if i%n==0] for x in xrange(len(seq))][:n]
Writing Python isn't a game of code golf, don't be afraid to use more than one line for the sake of readability.
l = [1,2,3,4,5,6,7,8]
def split_into_columns(input_list, num_of_cols=3):
retval = [ [] for _ in xrange(num_of_cols)] # build 3 columns
for i in xrange(len(input_list)): # iterate through original list
retval[i%num_of_cols].append(input_list[i]) # place in the "modulo 3" column
return retval
# here's a compressed, less readable version of that for-loop
#[retval[i%3].append(input_list[i]) for i in xrange(len(input_list))]
#return retval
print split_into_columns(l, 3)

Modifying nested lists

How to handle nested lists in Python? I am having problem figuring out the syntax. Like example:
>>> l = [[1, 2, 3], [5, 6, 7]]
I want to square all the elements in this list. I tried:
[m*m for m in l]
But that doesn't work and throws up:
TypeError: can't multiply sequence by
non-int of type 'list'
because of the nested lists I guess?
How do I fix this?
>>> l = [[1, 2, 3], [5, 6, 7]]
>>> [[e*e for e in m] for m in l]
|-nested list-|
|---- complete list ---|
[[1, 4, 9], [25, 36, 49]]
Assuming you wanted the answer to look like this:
[[1, 4, 9], [25, 36, 49]]
You could do something like this:
l = [[1, 2, 3], [5, 6, 7]]
for x in range(len(l)):
for y in range(len(l[x])):
l[x][y] = l[x][y] * l[x][y]
print l
Obviously, the list comprehension answer is better.
[[1,2,3],[4,5,6]] != [1,2,3,4,5,6]
[map(lambda x: x *x,sl) for sl in l] #List comprhension
What you need is a recursive function, something like this:
def square(el):
if type(el) == list:
return [square(x) for x in el]
else:
return el**2;
I'd rather not get into the correctness of type(el) == list here, but you get the gist.
Of course, this is also doable with a list-comprehension, as many people have pointer out, provided that the structure is always the same. This recursive function can handle any level of recursion, and lists containing both lists and numbers.

Categories