Related
I can't seem to figure out, how to change one array of the list at the time. It seems that I change every array of the list. But I want to change population of motifs one at the time with a mutationF method.
import random
import math
POPULIATION_SIZE = 5
chromosome = ["CGGGGCTGGGTCGTCACATTCCCCTTTCGATA", "TTTGAGGGTGCCCAATAACCAAAGCGGACAAA", "GGGATGCCGTTTGACGACCTAAATCAACGGCC", "AAGGCCAGGAGCGCCTTTGCTGGTTCTACCTG", "AATTTTCTAAAAAGATTATAATGTCGGTCCTC", "CTGCTGTACAACTGAGATCATGCTGCTTCAAC", "TACATGATCTTTTGTGGATGAGGGAATGATGC"]
motif_length = 8
motif_positions = [0 for i in range(len(chromosome))]
def mutationF(motif_pos):
for i in range(0, len(motif_pos)):
mutation = random.random()
if mutation <= 0.33 and motif_pos[i] - 1 >= 0:
motif_pos[i] = motif_pos[i] - 1
if mutation > 0.33 and mutation <= 0.66 and motif_pos[i] + 1 <= len(chromosome[0]) - motif_length:
motif_pos[i] = motif_pos[i] + 1
return motif_pos
repeat = False
population = []
for i in range(0, POPULIATION_SIZE):
population.append(motif_positions)
print(population)
while not repeat:
for i in range(0, POPULIATION_SIZE):
motif_positions2 = population[0]
motif_positions2 = mutationF(motif_positions2)
population.append(motif_positions2)
population.pop(0)
print(motif_positions2)
print(population)
repeat = True
Here are print results:
Tried some things which didn't seem to work.
for i in range(0, POPULIATION_SIZE):
population.append(motif_positions)
You are appending POPULIATION_SIZE references to the same list into population.
We can see this idea at work below:
>>> a = [4,5,6]
>>> b = []
>>> for _ in range(5): b.append(a)
...
>>> b
[[4, 5, 6], [4, 5, 6], [4, 5, 6], [4, 5, 6], [4, 5, 6]]
>>> b[1][0] = 1
>>> b
[[1, 5, 6], [1, 5, 6], [1, 5, 6], [1, 5, 6], [1, 5, 6]]
If you want to append multiplies copies of a list, the easiest way is to use [:] to make a copy of a list, as shown below.
>>> b = []
>>> for _ in range(5): b.append(a[:])
...
>>> b
[[1, 5, 6], [1, 5, 6], [1, 5, 6], [1, 5, 6], [1, 5, 6]]
>>> b[1][0] = 3
>>> b
[[1, 5, 6], [3, 5, 6], [1, 5, 6], [1, 5, 6], [1, 5, 6]]
The input is always strictly increasing. I could write this with a for loop and lots of if-else conditions, but is there some simple way? Here is an example:
input: [2,3,4,6,8,9]
output: [[0,1,2],[4,5]]
input: [1,2,3,4]
output: [[0,1,2,3]]
input: [0,1,2,4,6,7,8,10,12,13,14]
output: [[0,1,2], [4,5,6], [8,9,10]]
For example here is the code I wrote
def get_mergable_indices(sent_order):
mergable_indices = []
continuous_sents = [0]
for index, value in enumerate(sent_order):
if index == 0:
continue
else:
if value - sent_order[index-1] == 1:
continuous_sents.append(index)
else:
if len(continuous_sents)>1:
mergable_indices.append(continuous_sents)
continuous_sents = [index]
if len(continuous_sents)>1:
mergable_indices.append(continuous_sents)
return mergable_indices
It's too big want to reduce it
Maybe you can try this:
def get_mergable_indices(sent_order):
lst, res = [j-i for i, j in enumerate(sent_order)], []
ci = 0
for i in set(lst):
lci = lst.count(i)
if lci > 1:
res.append(list(range(ci, lci + ci)))
ci += lci
return res
output:
>>> get_mergable_indices([2,3,4,6,8,9])
[[0, 1, 2], [4, 5]]
>>> get_mergable_indices([1,2,3,4])
[[0, 1, 2, 3]]
>>> get_mergable_indices([0,1,2,4,6,7,8,10,12,13,14])
[[0, 1, 2], [4, 5, 6], [8, 9, 10]]
This can easily be done without using any module.
def get_mergable_indices(sent_order):
lst = sent_order
out = []
l = []
for a in range(max(lst)): # set range to the max number in the list.
try:
if lst[a]+1 == lst[a+1]: # check current number plus 1 is equal to next number
l.append(a)
l.append(a+1)
else: # if not equal then append l to the out list also set the l to an empty list.
if l:
out.append(list(set(l)))
l = []
except IndexError:
pass
out.append(list(set(l)))
return (out)
output
input: [2,3,4,6,8,9]
output: [[0,1,2],[4,5]]
input: [1,2,3,4]
output: [[0,1,2,3]]
input: [0,1,2,4,6,7,8,10,12,13,14]
output: [[0,1,2], [4,5,6], [8,9,10]]
This can accept any iterable sequence:
from itertools import pairwise
def get_mergable_indices(sent_order):
result = []
curr = []
for idx, (i, j) in enumerate(pairwise(sent_order)):
if j - i == 1:
curr.append(idx)
elif curr:
curr.append(idx)
result.append(curr)
curr = []
if curr:
curr.append(idx + 1)
result.append(curr)
return result
Output:
>>> get_mergable_indices([2, 3, 4, 6, 8, 9])
[[0, 1, 2], [4, 5]]
>>> get_mergable_indices(range(1, 5))
[[0, 1, 2, 3]]
>>> get_mergable_indices([0, 1, 2, 4, 6, 7, 8, 10, 12, 13, 14])
[[0, 1, 2], [4, 5, 6], [8, 9, 10]]
This is my approach:
def check_continuous(inp_list):
idx = idy = 0
res = [[]]
while idx < len(inp_list) - 1:
# Not append repeated indices
if inp_list[idx] - inp_list[idx+1] == -1: # If the next element is 1 higher, just check for -1
if idx not in res[idy]:
res[idy].append(idx)
if idx+1 not in res[idy]:
res[idy].append(idx+1)
else:
# Don't append empty lists
if res[idy]:
res.append([])
idy += 1
idx += 1
return res
print(check_continuous([2,3,4,6,8,9]))
# [[0, 1, 2], [4, 5]]
print(check_continuous([1,2,3,4]))
# [[0, 1, 2, 3]]
print(check_continuous([0,1,2,4,6,7,8,10,12,13,14]))
# [[0, 1, 2], [4, 5, 6], [8, 9, 10]]
I think this could be highly improved
As I have mentioned in the comments, np.diff can be a good choice in this regard. The accepted answer used two loops again, but is written in smaller form, and is not so different than other answers. The problem can be solved by Just NumPy as:
a = np.array([0, 1, 2, 4, 6, 7, 8, 10, 12, 13, 14])
diff = np.diff(a, prepend=a[0]-2) # [2 1 1 2 2 1 1 2 2 1 1]
diff_w = np.where(diff == 1)[0] # [ 1 2 5 6 9 10]
mask_ = np.diff(diff_w, prepend=diff_w[0]-2) # [2 1 3 1 3 1]
mask_ = mask_ != 1 # [ True False True False True False]
con_values = np.insert(diff_w, np.where(mask_)[0], diff_w[mask_] - 1) # [ 0 1 2 4 5 6 8 9 10]
# result = np.split(con_values, np.where(np.diff(con_values, prepend=con_values[0] - 1) != 1)[0])
result = np.split(con_values, np.where(np.diff(con_values, prepend=con_values[0] - 2) != 1)[0])[1:]
# [array([0, 1, 2], dtype=int64), array([4, 5, 6], dtype=int64), array([ 8, 9, 10], dtype=int64)]
I have tested this code on your examples and some others and it works. But, if there be any problem using other samples, it can be handled with some little changes by inspiration from this code. I wrote this code in separate parts to be understandable more. You can combine them in just one line if it is important for you.
I am trying to get the elements as a list if any of them in the same position in two 2D matrices.
Let's consider matrix A and matrix B
A = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]
B = [[0, 2, 5],[6, 2, 4],[7, 8, 1]]
The resultant list should be
C = [2, 7, 8]
I have tried using a filter but it is not working.
def find(A):
for i in range(3):
for j in range(3):
if A[i][j] == B[i][j]:
return A[i][j]
else:
return False
A = [[1, 2, 3],[4, 5, 6], [7, 8, 9]]
B = [[0, 2, 5],[6, 2, 4], [7, 8, 1]]
C = filter(find, A)
for element in C:
print(element)
Note: Please use a filter to achieve the target.
Solution using filter:
def find(L):
A, B = L
if A == B:
return True
else:
return False
A = [[1, 2, 3],[4, 5, 6], [7, 8, 9]]
B = [[0, 2, 5],[6, 2, 4], [7, 8, 1]]
# flatten lists
A = [item for row in A for item in row]
B = [item for row in B for item in row]
C = filter(find, zip(A,B))
# filter returns a tuple for each row but we only want the single element
C = [item[0] for item in C]
print(list(C))
Gives us
[2, 7, 8]
Try this,
def func(t):
return True if t[0] == t[1] else False
A = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]
B = [[0, 2, 5],[6, 2, 4],[7, 8, 1]]
C = [item1 for lst1, lst2 in zip(A, B) for item1, item2 in filter(func, zip(lst1, lst2))]
>>> C
[2, 7, 8]
Basic Answer
First we loop over A and B, i and z now holds the inner lists.
Then we loop over those inner lists using g and q, if they are equal, we append them to the empty list.
to_fill = []
for i,z in zip(A,B):
for g,q in zip(i,z):
if g==q:
to_fill.append(g)
Adapt it as you please.
The most efficient way of achieving what you want is by using numpy:
import numpy as np
A = np.asarray(A)
B = np.asarray(B)
C = A[A==B]
I have a list of list of list in python, which looks like this :
my_list = [ [[1,2,3],[4,3,2]] , [[2,1,9],[8,1,2]] , [[5,4,3],[1,6,7]] , ...]
would like to retrieve the max value of the list and its three indices.
I have seen how to do it for a list of list :
max_value, max_index = max((x, (i, j))
for i, row in enumerate(my_list)
for j, x in enumerate(row))
but I don't understand how to adapt it for a 3rd list.
Another question : Is there an easy way to apply the following operation on all the elements of my list ?
my_list = my_list - my_list[0] * 2
Just extend the concept?
max_value, max_index = max((x, (i, j, k))
for i, row in enumerate(my_list)
for j, col in enumerate(row))
for k, x in enumerate(col))
For your second question, look at the map function; it's designed for just this purpose.
map(lambda x: x - my_list[0] - 2, my_list)
Example:
>>> my_list = [5, 20, 22, 13, 8, 1000]
>>> map(lambda x: x - my_list[0] * 2, my_list)
[-5, 10, 12, 3, -2, 990]
Why not use numpy?
import numpy as np
lst = [[[1,2,3],[4,3,2]] , [[2,1,9],[8,1,2]] , [[5,4,3],[1,6,7]]]
a = np.array(lst) # Create numpy array from list
>>> a
Out[]:
array([[[1, 2, 3],
[4, 3, 2]],
[[2, 1, 9],
[8, 1, 2]],
[[5, 4, 3],
[1, 6, 7]]])
>>> a.tolist() # And convert back to list if needed
Out[]: [[[1, 2, 3], [4, 3, 2]], [[2, 1, 9], [8, 1, 2]], [[5, 4, 3], [1, 6, 7]]]
>>> a.tolist() == lst
Out[]: True
Get the indices of the maximum with:
>>> np.argwhere(a == a.max()) # Indices where a is maximum
Out[]: array([[1, 0, 2]], dtype=int64)
And apply your operation with:
a -= a[0] * 2 # Apply operation inplace
>>> a
Out[]:
array([[[-1, -2, -3],
[-4, -3, -2]],
[[ 0, -3, 3],
[ 0, -5, -2]],
[[ 3, 0, -3],
[-7, 0, 3]]])
So the solution I designed for the first problem first finds the max list from each row in the 3d list:
my_max_list = map(max, my_list)
Then incorporates your original solution for find the max element in a list of lists
max_value, max_index = max((x, (i, j))
for i, row in enumerate(my_max_list)
for j, x in enumerate(row))
For the second problem you can just use the map function
map(lambda x: x - my_list[0] * 2, my_list)
You can try this:
my_list = [ [[1,2,3],[4,3,2]] , [[2,1,9],[8,1,2]] , [[5,4,3],[1,6,7]]]
maximum, the_index = [(a, i) for i, a in enumerate(my_list) if a == max(my_list)][0]
new_list = [[[c-b[0]*2 for c in b] for b in i] for i in my_list]
I have a list of of lists like this:
nestedList = [[0],[0,1,2,3,4,6,7,8,9],[0,1,2,3,4,6,7,8,9],[1,2,3]]
and I have another homogeneous (same length) list of elements that I want to use to split the nestedList
lengthList = [[1],[5,4],[5,4],[3]]
I tried:
def split(arr, size):
arrs = []
while len(arr) > size:
pice = arr[:size]
arrs.append(pice)
arr = arr[size:]
arrs.append(arr)
return arrs
for i,j in zip(nestedList,lengthList):
for k in j:
myNewList.append(split(i,k))
but it doesn't work 100% right.
The output it gives is:
myNewList = [[[0]], [[0, 1, 2, 3, 4], [6, 7, 8, 9]], [[0, 1, 2, 3], [4, 6, 7, 8], [9]], [[0, 1, 2, 3, 4], [6, 7, 8, 9]], [[0, 1, 2, 3], [4, 6, 7, 8], [9]], [[1, 2, 3]]]
instead of
[[[0], [[0, 1, 2, 3, 4], [6, 7, 8, 9]], [[0, 1, 2, 3], [4, 6, 7, 8,9]], [[1, 2, 3]]]
Any help would be appreciated.
nestedList = [[0],[0,1,2,3,4,6,7,8,9],[0,1,2,3,4,6,7,8,9],[1,2,3]]
lengthList = [[1],[5,4],[5,4],[3]]
answer = []
for lens,sub in zip(lengthList, nestedList):
answer.append([])
top = 0
for l in lens:
answer[-1].append(sub[top:top+l])
top += l
Output:
In [2]: answer
Out[2]:
[[[0]],
[[0, 1, 2, 3, 4], [6, 7, 8, 9]],
[[0, 1, 2, 3, 4], [6, 7, 8, 9]],
[[1, 2, 3]]]
try this code
# stackoverflow.com
# Python
# split list into nested lists by values in a loop (iterating values)
nestedList = [[0],[0,1,2,3,4,6,7,8,9],[0,1,2,3,4,6,7,8,9],[1,2,3]]
lengthList = [[1],[5,4],[5,4],[3]]
def toOneList (array):
oneList = []
if len(array) > 0:
for subList in array:
for x in subList:
oneList.append(x)
return oneList
def grouping(array, size):
newList = []
i = 0
for j in size:
newList.append(array[i:i+j])
i = i + j
return newList
nestedList = toOneList(nestedList)
lengthList = toOneList(lengthList)
print(grouping(nestedList, lengthList))
Here is the solution you need
# stackoverflow.com
# Python
# split list into nested lists by values in a loop (iterating values)
nestedList = [[0],[0,1,2,3,4,6,7,8,9],[0,1,2,3,4,6,7,8,9],[1,2,3]]
lengthList = [[1],[5,4],[5,4],[3]]
def toOneList (array):
oneList = []
if len(array) > 0:
for subList in array:
for x in subList:
oneList.append(x)
return oneList
def grouping(array, size):
newList = []
i = 0
for j in size:
newList.append(array[i:i+j])
i = i + j
return newList
nestedList = toOneList(nestedList)
lengthList = toOneList(lengthList)
print(grouping(nestedList, lengthList))