Related
If I generate a list and try to remove a value (e.g.; 1) from a sub-list, it removes it from all sub-lists but if I use a pre-defined list (identical to the one created, the result is different. WHY?
The build function creates a matrix of x rows by x columns where the first item of each row is the row#
e.g.; [0,[1,2,3],[1,2,3],[1,2,3]] [1,[1,2,3],[1,2,3],[1,2,3]] [2,[1,2,3],[1,2,3],[1,2,3]]
def build(size):
values = []
activetable = []
for value in range(size): # create the list of possible values
values.append(value + 1)
for row in range(size):
# Create the "Active" table with all possible values
activetable.append([row])
for item in range(size):
activetable[row].append(values)
return activetable
This function is intended to remove a specific value in the list using the row and column coordinate
def remvalue(row, col, value, table):
before = table[row][col]
before.remove(value)
table[row][col] = before
return table
When I build a list and try to remove a value in a sub-list, it is removing it from all sub-list
print("start")
table1 = build(3) # this function create a 2d table called table1
print(f" table 1: {table1}")
newtable = remvalue(row=0, col=1, value=1, table=table1)
print(f"from a dynamic table : {newtable}")
As you can see the value "1" has been removed from all sub-lists
start
table 1: [[0, [1, 2, 3], [1, 2, 3], [1, 2, 3]], [1, [1, 2, 3], [1, 2, 3], [1, 2, 3]], [2, [1, 2, 3], [1, 2, 3], [1, 2, 3]]]
from a dynamic table : [[0, [2, 3], [2, 3], [2, 3]], [1, [2, 3], [2, 3], [2, 3]], [2, [2, 3], [2, 3], [2, 3]]]
But if I use a pre-defined list with exactly the same data, the result is different
table1 = [[0, [1, 2, 3], [1, 2, 3], [1, 2, 3]], [1, [1, 2, 3], [1, 2, 3], [1, 2, 3]], [2, [1, 2, 3], [1, 2, 3], [1, 2, 3]]]
newtable = remvalue(row=0, col=1, value=1, table=table1)
print(f"from a predefined table : {newtable}")
As you can see it works as desired only when I use a pre-defined list. Why do we have this difference?
start
table 1: [[0, [1, 2, 3], [1, 2, 3], [1, 2, 3]], [1, [1, 2, 3], [1, 2, 3], [1, 2, 3]], [2, [1, 2, 3], [1, 2, 3], [1, 2, 3]]]
from a dynamic table : [[0, [2, 3], [2, 3], [2, 3]], [1, [2, 3], [2, 3], [2, 3]], [2, [2, 3], [2, 3], [2, 3]]]
from a predefined table : [[0, [2, 3], [1, 2, 3], [1, 2, 3]], [1, [1, 2, 3], [1, 2, 3], [1, 2, 3]], [2, [1, 2, 3], [1, 2, 3], [1, 2, 3]]]
Given a nested list say:
a = [[1, 5, 100],
[2],
[2, 100]]
The desired result to be obtained is as follows:
[[1, 2, 5], [1, 2, 100], [5, 2, 100], [100, 2, 5]]
Here is my code, but it does not give the output as desired. I am unable to progress further:
arr = [[i] for i in a[0]]
def poss(j, arr, tmp):
for i in range(len(tmp)):
arr[i] = tmp[i] + [j]
print(arr)
for i in a[1:]:
tmp = [k for k in arr] # deepcopy of arr
for j in i:
poss(j, arr, tmp)
Output for above code:
[[1, 2], [5, 2], [100, 2]]
[[1, 2, 5], [5, 2, 5], [100, 2, 5]]
[[1, 2, 100], [5, 2, 100], [100, 2, 100]]
I also feel this code is inefficient on large data, is that so? I'm looking for a better code to get the result.
This problem can be solved by using itertools module of python.
The itertools.combinations() function returns all the possible subsets of the given set without repetition of elements.
import math
import itertools
a = [[1, 5, 100],
[2],
[2, 100]]
dimx = max([len(el) for el in a])
uniqueEls={}
for el in a:
for subel in el:
uniqueEls[subel] = uniqueEls.get(subel,0)
desiredArr= [list(x) for x in list(itertools.combinations(uniqueEls.keys(), dimx))]
print(desiredArr)
[[1, 5, 100], [1, 5, 2], [1, 100, 2], [5, 100, 2]]
a1=[[1, 2], [2, 3], [2, 4],[3, 4] ,[3, 6], [4, 5]]
i want the output to be:
a1=[[1, 2], [2, 3], [3, 4], [4, 5]]
I've tried removing it with a for loop, but it throws an error index out of range
You can use pop() if you want to remove by index (e.g. the fourth element):
In [1]: a1 = [[1, 2], [2, 3], [2, 4],[3, 4] ,[3, 6], [4, 5]]
In [2]: a1.pop(4)
Out[2]: [3, 6]
In [3]: a1
Out[3]: [[1, 2], [2, 3], [2, 4], [3, 4], [4, 5]]
Or, you can remove by specifying the element:
In [4]: a1 = [[1, 2], [2, 3], [2, 4],[3, 4] ,[3, 6], [4, 5]]
In [5]: a1.remove([3, 6])
In [6]: a1
Out[6]: [[1, 2], [2, 3], [2, 4], [3, 4], [4, 5]]
The answer is very simple just use the pop function.
https://www.geeksforgeeks.org/python-list-pop/
For your case it would be :
a1.pop(4)
you can loop over the Pop() function to remove multiple ones.
given input: theList = [<userID>,<number_of_views>]
theList = [
[[3, 5], [1, 1], [2, 3]],
[[1, 2], [3, 5], [3, 0], [2, 3], [4, 2]],
[[1, 2], [3, 5], [3, 0], [2, 3], [4, 2]],
[[1, 2], [1, 1], [4, 2]]
]
expected output = [
[[3, 5], [2, 3], [1, 1]],
[[3, 5], [2, 3], [1, 2], [4, 2]],
[[3, 5], [2, 3], [1, 2], [4, 2]],
[[1, 3], [4, 2]]
]
for sublist in theList:
e.x -->
theList[3] = [[1,2], [1,1], [4,2]]
how to merge items that have same userIDs = 1 in this case and sum all the corresponding views to this (userID=1) (2+1) = 3 views into a new_list --> [1,3]
expected theList[3] = [[1,3], [4,2]].
How could I make this process for all theList?
Thanks so much for spending time on this question!
This is one approach using collections.defaultdict.
Ex:
from collections import defaultdict
theList = [
[[3, 5], [1, 1], [2, 3]],
[[1, 2], [3, 5], [3, 0], [2, 3], [4, 2]],
[[1, 2], [3, 5], [3, 0], [2, 3], [4, 2]],
[[1, 2], [1, 1], [4, 2]]
]
result = []
for i in theList:
r = defaultdict(int)
for j, k in i:
r[j] += k
result.append(list(r.items()))
print(result)
Output:
[[(3, 5), (1, 1), (2, 3)],
[(1, 2), (3, 5), (2, 3), (4, 2)],
[(1, 2), (3, 5), (2, 3), (4, 2)],
[(1, 3), (4, 2)]]
Suppose I have an array lets say [1,2,3,4]:
I want to find the sum as follows:
First I generate pairs like:
(1 2 3 4)
(123)(4)
(1)(234)
(12)(34)
(12)(3)(4)
(1)(23)(4)
(1)(2)(34)
(1)(2)(3)(4)
The ans would then be sum of elements in one group multiplied by the length of that group(for all possible groups)
eg in the arrangement (123)(4), the sum would be
(1+2+3)*3 + (4)*1
I just want the final sum which is sum of all such values , not the actual groups. How can I do this?
I was able to do it by first generating all possible groups and then finding the sum
But since I only need the sum and not the actual groups, is there a better way?
The number of arrangements is 2**(len(L)-1). A list of 8 elements produce 128 different arrangements. It is an exponential problem. You either generate all possible solutions and then calculate each answer, or you calculate each answer on the fly. Either way it is still exp.
def part1(L, start, lsum):
if start == len(L):
print lsum
else:
for i in range(start, len(L)):
left = sum(L[start:i+1]) * (i-start+1)
part1(L, i + 1, lsum + left)
def part2(L, M, X, start):
if start == len(L):
M.append(X)
print sum([sum(x) * len(x) for x in X])
else:
for i in range(start, len(L)):
part2(L, M, X + [L[start:i+1]], i + 1)
ex:
>>> part1(L, 0, 0)
10
17
15
28
13
20
22
40
>>> M = []
>>> part2(L, M, [], 0)
10
17
15
28
13
20
22
40
edit: sum of all the sums in O(n**3)
for L = [1,2,3,4,5,6]
[[[1], [2], [3], [4], [5], [6]],
[[1], [2], [3], [4], [5, 6]],
[[1], [2], [3], [4, 5], [6]],
[[1], [2], [3], [4, 5, 6]],
[[1], [2], [3, 4], [5], [6]],
[[1], [2], [3, 4], [5, 6]],
[[1], [2], [3, 4, 5], [6]],
[[1], [2], [3, 4, 5, 6]],
[[1], [2, 3], [4], [5], [6]],
[[1], [2, 3], [4], [5, 6]],
[[1], [2, 3], [4, 5], [6]],
[[1], [2, 3], [4, 5, 6]],
[[1], [2, 3, 4], [5], [6]],
[[1], [2, 3, 4], [5, 6]],
[[1], [2, 3, 4, 5], [6]],
[[1], [2, 3, 4, 5, 6]],
[[1, 2], [3], [4], [5], [6]],
[[1, 2], [3], [4], [5, 6]],
[[1, 2], [3], [4, 5], [6]],
[[1, 2], [3], [4, 5, 6]],
[[1, 2], [3, 4], [5], [6]],
[[1, 2], [3, 4], [5, 6]],
[[1, 2], [3, 4, 5], [6]],
[[1, 2], [3, 4, 5, 6]],
[[1, 2, 3], [4], [5], [6]],
[[1, 2, 3], [4], [5, 6]],
[[1, 2, 3], [4, 5], [6]],
[[1, 2, 3], [4, 5, 6]],
[[1, 2, 3, 4], [5], [6]],
[[1, 2, 3, 4], [5, 6]],
[[1, 2, 3, 4, 5], [6]],
[[1, 2, 3, 4, 5, 6]]]
There seems to be a pattern. The odd case is: the sets having the first elements of the sequence as the smallest element as the sorted set, there are 32. But then all the rest there are 16. For each element of the list, I add all the sets which contains that element as the first sorted element.
def part3(L):
ret = 0
for i in range(len(L)):
p = 0
for k in range(len(L) - i - 1):
p += sum(L[i:i+k+1]) * (k+1) * 2**(len(L) - i - k - 2)
p += sum(L[i:]) * (len(L) - i)
ret += p * max(1, 2**(i-1))
return ret
edit2: to lower it to O(n^2) you need to use DP. building a table of sums to calculate each sum in O(1). You build an array S with S[i] = S[i-1] + L[i] and sum(L[a:b]) is S[b] - S[a].