Operator on array in python - python

I would like to know how to extract sub_arrayes from an array(which can be in different sizes). Therefore, by given an array I want a sum of sub array elements like:
Array = [1, 2, 3]
SubArray = [(1),(2),(3),(1,2),(2,3),(1,2,3)]
My question is, how to create such a sub array for an array with different size and how to XOR subArray elements as a final result in python.
I don't want to use numpy!

You could use:
sublist = []
for i in range(1, len(mylist)+1): # number of items in sublist
for j in range(len(mylist)-i+1): # index of sublist
sublist.append( tuple(mylist[j:j+i]) )
For the second problem (xor-ing all elements), you can use:
result = 0
for sub in sublist:
for e in sub:
result ^= e
However, if you don't need sublist after this, you can just do:
sublist = []
for i in range(1, len(mylist)+1): # number of items in sublist
for j in range(len(mylist)-i+1): # index of sublist
for e in mylist[j:j+i]:
result ^= e
This removes some redundancy.

You can use something like this:
itertools.chain(*(itertools.combinations(Array, r=r) for r in range(1, len(Array)+1)))

Related

Multiplying each row by every element in python

I have these type of two matrices:
import itertools
import random
tem_1 = itertools.count(1)
A = [[next(tem_1) for i in range(8)] for j in range(4)]
tem_2 = itertools.count(1)
B = [[next(tem_2) for i in range(10)] for j in range(32)]
I want to multiply each row of B with every corresponding element of of A. I will multiply all the first 10 numbers of matrix B with 1, the next 10 numbers ( row2 in B) with 2 and so on.
How do I do this?
Forget about creating A and do
for idx, i in enumerate(k for k in range(1, 33)):
B[idx] = [i * j for j in B[idx]]
If you need to start from some version of A with the form in the question, you can flatten it first then use it as the argument to enumerate above
flat_A = (item for sublist in A for item in sublist)
That creates a generator object that yields every subelement of A though you could use square brackets to create a list of all the subelements.

Save list number within a list only if it contains elements in python

I have list of lists such as :
my_list_of_list=[['A','B','C','E'],['A','B','C','E','F'],['D','G','A'],['X','Z'],['D','M'],['B','G'],['X','Z']]
as you can see, the list 1 and 2 share the most elements (4). So, I keep a list within my_list_of_list only if the 4 shared elements (A,B,C or E) are present within that list.
Here I then save within the list_shared_number[], only the lists 1,2,3 and 6 since the other does not contain (A,B,C or E).
Expected output:
print(list_shared_number)
[0,1,2,5]
Probably sub optimal because I need to iterate 3 times over lists but it's the expect result:
from itertools import combinations
from functools import reduce
common_elements = [set(i).intersection(j)
for i, j in combinations(my_list_of_list, r=2)]
common_element = reduce(lambda i, j: i if len(i) >= len(j) else j, common_elements)
list_shared_number = [idx for idx, l in enumerate(my_list_of_list)
if common_element.intersection(l)]
print(list_shared_number)
# Output
[0, 1, 2, 5]
Alternative with 2 iterations:
common_element = {}
for i, j in combinations(my_list_of_list, r=2):
c = set(i).intersection(j)
common_element = c if len(c) > len(common_element) else common_element
list_shared_number = [idx for idx, l in enumerate(my_list_of_list)
if common_element.intersection(l)]
print(list_shared_number)
# Output
[0, 1, 2, 5]
You can find shared elements by using list comprehension. Checking if index 0 and index 1:
share = [x for x in my_list_of_list[0] if x in my_list_of_list[1]]
print(share)
Assume j is each item so [j for j in x if j in share] can find shared inner elements. if the length of this array is more than 0 so it should include in the output.
So final code is like this:
share = [x for x in my_list_of_list[0] if x in my_list_of_list[1]]
my_list = [i for i, x in enumerate(my_list_of_list) if len([j for j in x if j in share]) > 0]
print(my_list)
You can use itertools.combinations and set operations.
In the first line, you find the intersection that is the longest among pairs of lists. In the second line, you iterate over my_list_of_list to identify the lists that contain elements from the set you found in the first line.
from itertools import combinations
comparison = max(map(lambda x: (len(set(x[0]).intersection(x[1])), set(x[0]).intersection(x[1])), combinations(my_list_of_list, 2)))[1]
out = [i for i, lst in enumerate(my_list_of_list) if comparison - set(lst) != comparison]
Output:
[0, 1, 2, 5]
Oh boy, so mine is a bit messy, however I did not use any imports AND I included the initial "finding" of the two lists which have the most in common with one another. This can easily be optimised but it does do exactly what you wanted.
my_list_of_list=[['A','B','C','E'],['A','B','C','E','F'],['D','G','A'],['X','Z'],['D','M'],['B','G'],['X','Z']]
my_list_of_list = list(map(set,my_list_of_list))
mostIntersects = [0, (None,)]
for i, IndSet in enumerate(my_list_of_list):
for j in range(i+1,len(my_list_of_list)):
intersects = len(IndSet.intersection(my_list_of_list[j]))
if intersects > mostIntersects[0]: mostIntersects = [intersects, (i,j)]
FinalIntersection = set(my_list_of_list[mostIntersects[1][0]]).intersection(my_list_of_list[mostIntersects[1][1]])
skipIndexes = set(mostIntersects[1])
for i,sub_list in enumerate(my_list_of_list):
[skipIndexes.add(i) for char in sub_list
if i not in skipIndexes and char in FinalIntersection]
print(*map(list,(mostIntersects, FinalIntersection, skipIndexes)), sep = '\n')
The print provides this :
[4, (0, 1)]
['E', 'C', 'B', 'A']
[0, 1, 2, 5]
This works by first converting the lists to sets using the map function (it has to be turned back into a list so i can use len and iterate properly) I then intersect each list with the others in the list of lists and count how many elements are in each. Each time i find one with a larger number, i set mostIntersections equal to the len and the set indexes. Once i go through them all, i get the lists at the two indexes (0 and 1 in this case) and intersect them to give a list of elements [A,B,C,E] (var:finalIntersection). From there, i just iterate over all lists which are not already being used and just check if any of the elements are found in finalIntersection. If one is, the index of the list is appended to skipIndexes. This results in the final list of indexes {indices? idk} that you were after. Technically the result is a set, but to convert it back you can just use list({0,1,2,5}) which will give you the value you were after.

how to sum up elements in list of lists for arbitrary combination in python

I have a list like this,
A = [[0.8922063, 0.26672425],
[0.34475611, 0.35976697],
[0.33253499, 0.18923898],
[0.66872466, 0.46248986],
[0.72823733, 0.10537784],
[0.40903598, 0.70639412],
[0.79926596, 0.90095583],
[0.67886544, 0.84573289],
[0.3641813, 0.64296743],
[0.07461196, 0.74290527]]
which is the combination of lists of list
and I have another list
p = [5,4,2]
I need to sum up elements of list A corresponding to P, i.e, the sum of the first 5 sub-list of A, then the sum of the next 4 (6th to 9th) sub-list and finally the sum of the last 2 sub-list.
Transform your list p into a list of the slices you want:
>>> q = [0,5,9,10]
You can do that this way:
>>> q = [sum(p[:i]) for i in range(len(p)+1)]
Then sum the slices of A:
>>> for i in range(len(q)-1):
listn = sum(sum(x) for x in A[q[i]:q[i+1]])
print(listn)
4.35005729
5.34739895
0.81751723
This function returns a list of sums from chunks in A by keeping track of our last sliced element (starting at 0) and incrementing the index to slice with the numbers in p.
def sum_sublists(list1 : list, list2 : list) -> list:
sums=[]
last_slice = 0
for chunk_size in list2:
next_slice = last_slice+chunk_size
sums.append(sum([sum(el) for el in list1[last_slice:next_slice]]))
last_slice = next_slice
return sums
if __name__ == '__main__':
p = [5,4,1]
A = [[0.8922063, 0.26672425],
[0.34475611, 0.35976697],
[0.33253499, 0.18923898],
[0.66872466, 0.46248986],
[0.72823733, 0.10537784],
[0.40903598, 0.70639412],
[0.79926596, 0.90095583],
[0.67886544, 0.84573289],
[0.3641813, 0.64296743],
[0.07461196, 0.74290527],
]
print(sum_sublists(A, p))

Function squaring 2-d array python

I have a function that takes in any 2-d array and return a 2-d array (the same format as the array being implemented) but the values are squared.
i.e [[1,2],[3,4]] -----> [[1,4],[9,16]]
my code so far:
m0 = [[1,2],[3,4]]
empty_list = []
for x in m0:
for i in x:
empyt_list.append(x**2)
This gives me a 1-d array but how would i return a 2-d array as the imputed value?
You can make a recursive function to handle any depth of nested lists:
def SquareList(L):
if type(L) is list:
return [SquareList(x) for x in L]
else:
return L**2
Example:
> print(SquareList([1,[3],[2,[3]],4]))
[1, [9], [4, [9]], 16]
Working with an outer list
The point is that you will need an extra list outside to store the columns. So we can introduce temporary lists we build up and add as rows:
m0 = [[1,2],[3,4]]
result = []
for sublist in m0:
row = []
for item in sublist:
row.append(item**2)
result.append(row)
Notice that we here iterate over the items of the sublist.
Using list comprehension
We can however write this more elegantly with list comprehension
result = [[x*x for x in sublist] for sublist in m0]
Note: if you have to square a number x, it is usually more efficient to use x * x, then to write x ** 2.
Using numpy (for rectangular lists)
In case the list is rectangular (all sublists have the same length), we can use numpy instead:
from numpy import array
a0 = array(m0)
result = a0 ** 2
You can just do this by a list comprehension:
empty_list = [[m0[i][j]**2 for j in range(len(m0[i]))] for i in range(len(m0))]
Or like your Codestyle:
empty_list = m0
for i in range(len(m0)):
for j in range(len(m0[i])):
empty_list[i][j] = m0[i][j] ** 2
Your problem is that you never created a 2D-list and you just append the values on the created 1D-list.

how to extract numbers from each position of a python list of lists

I have a list :
N=[[0,3,4], [0,1,2,9,3], [0,3]]
How do i get it so use ths list to get another list with each list item being a number for each positon of the list items in N so that the new list looks like:
newList=[[0,0,0], [3,1,3], [4,2] ,[9], [3]]
so he first item in newList is a sublist that contains the first number in N[0], the first number in N[1], and the first number in N[2]. The next sublist in N will do the same just for the second positions.
Could make use of izip_longest, then filter out the default values, eg:
from itertools import izip_longest
N=[[0,3,4], [0,1,2,9,3], [0,3]]
new_list = [[el for el in items if el is not None] for items in izip_longest(*N)]
# [[0, 0, 0], [3, 1, 3], [4, 2], [9], [3]]
Try the list comprehension
newList= [reduce(lambda x,y: x + [y[i]] if i<len(y) else x, N, [])
for i in range(max(map(len,N)))]
The for just iterates i upto the length of the longest sublist in N, using map with len to construct a temporary list of the lengths of the lists in N to calculate the max length.
The reduce builds up each sublist in the result by picking out the ith element of the corresponding input sublist -- but only if that sublist is long enough.
A weird and inneficient way (but maybe easy to understand would be):
Get maximum length of the lists in N
Iterate all those lists from 0 to that maximum.
If you got an error, that's because your original list (the one that came from N) doesn't have that item
N=[[0,3,4], [0,1,2,9,3], [0,3]]
newList = []
max_items = max([len(lst) for lst in N])
for n_lst in N:
for i in range(max_items):
if len(newList) <= i:
newList.append([])
try:
newList[i].append(n_lst[i])
except IndexError:
pass
print "new List: %s" % newList
Another approach, that maybe makes the code cleaner is initializing newList to a list with 5 items, since the longest list on your matrix N ([0,1,2,9,3]) has 5 elements. That way you know that your result (the newList variable) is going to have 5 lists:
N=[[0,3,4], [0,1,2,9,3], [0,3]]
newList = []
max_items = max([len(lst) for lst in N])
newList=list([] for _ in range(max_items))
for i in range(max_items):
for n_lst in N:
if len(n_lst) > i:
newList[i].append(n_lst[i])
print "new List: %s" % newList
Note that instead of catching an IndexException, you can also check if the len() of the list you're evaluating is > i
EDIT:
Just saw John Clements response (https://stackoverflow.com/a/22901233/289011) which is by far the cleaner.
How about the following:
# original list
N = [[0,3,4], [0,1,2,9,3], [0,3]]
# create a new list of `n` lists (n being the length of the longest sublist in N)
newList = [[] for i in xrange(max([len(l) for l in N]))]
# iterate over each list
# enumerate - use the index to append into correct target list
for l in N:
for i, val in enumerate(l):
newList[i].append(val)
print newList
Yields:
[[0, 0, 0], [3, 1, 3], [4, 2], [9], [3]]
Hope this helps! :)
Here is a solution that does not use list comprehensions, but also does not require a pre-processing step to determine maximum list length.
N = [[0,3,4], [0,1,2,9,3], [0,3]]
newList = []
progress = True
i = 0;
while (progress):
progress = False
sublist = []
for list in N:
if len(list) <= i:
continue
else:
sublist.append(list[i])
progress = True
if not progress:
break
newList.append(sublist)
i = i+1
print(N)
print(newList)

Categories