Appending the Sum of the Number of Rows Present - python

Here is my code:
def dictListSum(dictionary):
temporary_list = []
final_list = []
for (key, value) in sorted(dictionary.items()):
temporary_list.append(value[0:])
nRows = len(temporary_list)
nCols = len(temporary_list[0])
for row in range(0, nRows-1):
for col in range(0, nCols):
final_list.append(temporary_list[row][col] + temporary_list[row + 1][col])
return final_list
I'm having issues dealing with this line:
final_list.append(temporary_list[row][col] + temporary_list[row + 1][col])
Here's the format I would expect from the user's dictionary input:
a = {'A': [3, 11, 2], 'B': [5, 2, 0]}
Now, the code runs just fine if the user's dictionary has only two keys. The problem for me starts to occur when the users inputs something like this:
a = {'A':[4, 5, 2, 5, 6, 3], 'B': [4, 5, 6, 2, 4, 6], 'C': [1, 1, 1, 1, 1, 1,], 'D': [2, 2, 2, 2, 2, 2]}
If this was the case, my troublesome line of code would have to look like this:
final_list.append(temporary_list[row][col] + temporary_list[row + 1][col] temporary_list[row + 2][col] temporary_list[row + 3][col])
So, how would I be able to add all the rows (lists present) together in a sequential format? Keep in mind that the user gets to create as many keys as he/she wants, provided they are of the same length and are in a list format.
An example output that would be wrong (using the latter dictionary):
a = {'A':[4, 5, 2, 5, 6, 3], 'B': [4, 5, 6, 2, 4, 6], 'C': [1, 1, 1, 1, 1, 1,], 'D': [2, 2, 2, 2, 2, 2]}
dictListSum(a)
[8, 10, 8, 7, 10, 9, 5, 6, 7, 3, 5, 7, 3, 3, 3, 3, 3, 3]
What should happen:
dictListSum(a)
[11, 13, 11, 10, 13, 12]

One way to think about this: view the values of your dictionary as the rows of a table, and then sum along the columns. i.e. convert this:
[4, 5, 2, 5, 6, 3],
[4, 5, 6, 2, 4, 6],
[1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2]
to this:
[4, 4, 1, 2],
[5, 5, 1, 2],
[6, 2, 1, 2],
[2, 5, 1, 2],
[4, 6, 1, 2],
[6, 3, 1, 2]
...and then sum the lists. To achieve that:
[sum(lst) for lst in zip(*a.values())]
zip(*lists) is a pattern that is basically equivalent to "transposing" a "matrix"; then, we just sum along each of the "rows" (lst).

Related

Convert lists into higher dimension so that elements can be reached by following

I have a matrix that I want to convert to 3D so that I can be able to print the element of list[i][j][k]
a = [[[0, 1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6], [2, 3, 2, 3, 4,5], [3, 2, 3, 4, 3, 4], [4, 3, 4, 5, 4, 3], [5, 4, 5, 6, 5, 4]]]
print(a[5][5][0]) # I want to be able to print in 3D`
I get right output if I do a[5][5] but wrong when I add the [0]. Is there anyway of converting my matrix such that this will be solved?
I tried to just wrap the list up with brackets [list], but it did not work. I also did:
b = [[i] for i in a]
which gave me [[[0,1,2,3,4,5]],[[1,2,3,4,5,6]],...
and it still did not work!
NOTE: I want the i to be the row, j to be the column and k to be 0 or 1, so k = 0 (in which case the value is the row index of the cell is pointing to), or the k = 1 (the value is the column index).
Tried to reproduce your issue. To me, it works if you use the right index. Here, it perfectly works if you do for instance
print(a[0][0][5]) # I want to be able to print in 3D`
for list a = [[[0, 1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6], [2, 3, 2, 3, 4,5], [3, 2, 3, 4, 3, 4], [4, 3, 4, 5, 4, 3], [5, 4, 5, 6, 5, 4]]] you have just a[0][n][n]. You can try a[0][5][5]
You have index like below:
a = [
#0 element i
[
#0 element j
[0, 1, 2, 3, 4, 5],
#1 element j
[1, 2, 3, 4, 5, 6],
#2 element j
[2, 3, 2, 3, 4,5],
#3 element j
[3, 2, 3, 4, 3, 4],
#4 element j
[4, 3, 4, 5, 4, 3],
#5 element j
[5, 4, 5, 6, 5, 4]
]
]
print(a[0][5][5]) # a[i][j][k]

sample n random permutations of a list in python [duplicate]

This question already has answers here:
python shuffling with a parameter to get the same result
(4 answers)
Closed 1 year ago.
I have a list of values such as:
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
and I need to reproducibly return n random shuffles of this list.
Ideally, I need a function with seed such that f(lst, samples = 2, seed = 1234)
-> return two shuffles of the list lst such as:
[5, 7, 1, 6, 2, 8, 0, 4, 3, 9]
[8, 7, 3, 0, 1, 4, 5, 9, 6, 2]
Repeated execution of this function (with the same seed) would return the same two lists.
This works without numpy:
import sys
import random
some_seed = 123 # change this to get different shuffles
def n_shuffles(lst, n):
r = random.Random(some_seed)
for _ in range(n):
_l = lst[:]
r.shuffle(_l)
yield _l
l = list(range(10))
>>> [*n_shuffles(l, 3)]
[[8, 7, 5, 9, 2, 3, 6, 1, 4, 0], [7, 6, 3, 4, 1, 0, 2, 5, 9, 8], [1, 8, 5, 6, 4, 7, 9, 0, 2, 3]]
>>> [*n_shuffles(l, 3)]
[[8, 7, 5, 9, 2, 3, 6, 1, 4, 0], [7, 6, 3, 4, 1, 0, 2, 5, 9, 8], [1, 8, 5, 6, 4, 7, 9, 0, 2, 3]]
You can use np.copy
import numpy as np
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
def shuffle_list(arr:list,samples:int,seed:int):
np.random.seed(seed)
res = []
for i in range(samples):
arr_copy=np.copy(arr)
np.random.shuffle(arr_copy)
res.append(arr_copy)
return res
#test
print(shuffle_list(lst,2,1234))
output:
[array([7, 2, 9, 1, 0, 8, 4, 5, 6, 3]), array([7, 3, 5, 1, 4, 8, 0, 2, 6, 9])]
Ok, it wasn't an exact duplicate, but the proposed topic has pretty much shown that re-setting the seed() is the key:
import random
def shuffles(l,n):
random.seed(4) # just the same one as in the referred topic
return [random.sample(l,k=len(l)) for i in range(n)]
print(shuffles([1,2,3,4],3))
print("again:")
print(shuffles([1,2,3,4],3))
will generate
[[2, 4, 1, 3], [4, 1, 3, 2], [1, 2, 3, 4]]
again:
[[2, 4, 1, 3], [4, 1, 3, 2], [1, 2, 3, 4]]

Problem involving 'alphabetization' of sets of row elements

Consider a variable setSize (it can take value 2 or 3), and a numpy array v.
The number of columns in v is divisible by setSize. Here's a small sample:
import numpy as np
setSize = 2
# the array spaces are shown to emphasize that the rows
# are made up of sets having, in this case, 2 elements each.
v = np.array([[2,5, 3,5, 1,8],
[4,6, 2,7, 5,9],
[1,8, 2,3, 1,4],
[2,8, 1,4, 3,5],
[5,7, 2,3, 7,8],
[1,2, 4,6, 3,5],
[3,5, 2,8, 1,4]])
PROBLEM: For the rows that have all elements unique, I need to ALPHABETIZE the sets.
For example: set 1,14 would precede set 3,5, which would precede set 5,1.
As a final step, I need to eliminate any duplicated rows that may result.
In this example above, the array rows having indices 1,3,5,and 6 have unique elements,
so these rows must be alphabetized. The other rows are not changed.
Further, the rows v[3] and v[6], after alphabetization, are now identical. One of them may be dropped.
The final output looks like:
v = [[2,5, 3,5, 1,8],
[2,7, 4,6, 5,9],
[1,8, 2,3, 1,4],
[1,4, 2,8, 3,5],
[5,7, 2,3, 7,8],
[1,2, 3,5, 4,6]]
I can identify the rows having unique elements with code like below, but I stuck with the alphabetization code.
s = np.sort(v,axis=1)
v[(s[:,:-1] != s[:,1:]).all(1)]
Assuming you have unsuitable rows dropped with:
s = np.sort(v, axis=1)
idx = (s[:,:-1] != s[:,1:]).all(1)
w = v[idx]
Then you can get orders of each row with np.lexsort on a reshaped array:
w = w.reshape(-1,3,2)
s = np.lexsort((w[:,:,1], w[:,:,0]))
Then you can apply fancy indexing and reshape it back:
rows, orders = np.repeat(np.arange(len(s)), 3), s.flatten()
v[idx] = w[rows, orders].reshape((-1,6))
If you need to drop duplicated rows, you can do it like so:
u, idx = np.unique(v, return_index=True, axis=0)
output = v[np.sort(idx)]
Visualization of process:
Sample run:
>>> s
array([[1, 0, 2],
[1, 0, 2],
[0, 2, 1],
[2, 1, 0]], dtype=int64)
>>> rows
array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3])
>>> orders
array([1, 0, 2, 1, 0, 2, 0, 2, 1, 2, 1, 0], dtype=int64)
>>> v[idx]
array([[2, 7, 4, 6, 5, 9],
[1, 4, 2, 8, 3, 5],
[1, 2, 3, 5, 4, 6],
[1, 4, 2, 8, 3, 5]])
>>> v
array([[2, 5, 3, 5, 1, 8],
[2, 7, 4, 6, 5, 9],
[1, 8, 2, 3, 1, 4],
[1, 4, 2, 8, 3, 5],
[5, 7, 2, 3, 7, 8],
[1, 2, 3, 5, 4, 6],
[1, 4, 2, 8, 3, 5]])
>>> output
array([[2, 5, 3, 5, 1, 8],
[2, 7, 4, 6, 5, 9],
[1, 8, 2, 3, 1, 4],
[1, 4, 2, 8, 3, 5],
[5, 7, 2, 3, 7, 8],
[1, 2, 3, 5, 4, 6]])

Form groups in a list based on condition

(Edited based on feedbacks)
I've got a list like this:
my_list = [1,2,3,1,2,4,1,3,5,1,4,6,1,4,7]
That I'm struggling to turn into that:
result = [[1,2,3,1,2,4],[1,3,5],[1,4,6,1,4,7]]
I want to group my_list elements in sublists of 3 elements unless my_list[i] = my_list[i+3] in this case I want to merge those in bigger sublists.
Here is what I've tried:
result = []
for i in range(1,len(my_list),3):
try:
print(my_list[i],my_list[i+3])
if my_list[i] == my_list[i+3]:
result.extend(my_list[i-1:i+5])
else:
result.append(my_list[i-1:i+2])
FWIW, the description of your logic isn't quite clear. However, if I understand your code correctly, I think this is at least something in the correct direction:
def stepper(my_list, step, bigger_step):
res = []
idx = 0
while idx <= len(my_list)-1:
if idx + step > len(my_list)-1:
# Remove this append if you don't want the "leftovers"
res.append(my_list[idx:])
break
if my_list[idx] != my_list[idx+step]:
res.append(my_list[idx:idx+step])
idx += step
else:
res.append(my_list[idx:idx+bigger_step])
idx += bigger_step
return res
my_list = [1,2,3,1,2,4,1,3,5,1,3,6,1,2,7]
print(stepper(my_list, step=3, bigger_step=6)) # Output: [[1, 2, 3, 1, 2, 4], [1, 3, 5, 1, 3, 6], [1, 2, 7]]
Note that the above output is different from your given example, because of your given logic that you've provided makes the second sub-list extended as well as the first.
Using the above code, we can check the results if we change bigger_step easily with a for-loop:
for big in range(4, 10):
print(f"Step: 3, Bigger_Step: {big}, Result:{stepper(my_list, step=3, bigger_step=big)}")
Output:
Step: 3, Bigger_Step: 4, Result:[[1, 2, 3, 1], [2, 4, 1], [3, 5, 1, 3], [6, 1, 2], [7]]
Step: 3, Bigger_Step: 5, Result:[[1, 2, 3, 1, 2], [4, 1, 3], [5, 1, 3], [6, 1, 2], [7]]
Step: 3, Bigger_Step: 6, Result:[[1, 2, 3, 1, 2, 4], [1, 3, 5, 1, 3, 6], [1, 2, 7]]
Step: 3, Bigger_Step: 7, Result:[[1, 2, 3, 1, 2, 4, 1], [3, 5, 1, 3, 6, 1, 2], [7]]
Step: 3, Bigger_Step: 8, Result:[[1, 2, 3, 1, 2, 4, 1, 3], [5, 1, 3], [6, 1, 2], [7]]
Step: 3, Bigger_Step: 9, Result:[[1, 2, 3, 1, 2, 4, 1, 3, 5], [1, 3, 6, 1, 2, 7]]

Python consecutive operations on list getting executed in wrong order

I have a function written in python that performs some consecutive operations on two lists. The problem is that at random times during the execution of these functions, they give wrong answer. The code inside the function is
def temp(c, p):
random.seed(0)
x = random.randint(0 , len(c)-1)
y = random.randint(0 , len(c)-1)
s_1 = c[x][0]
s_2 = c[y][0]
p[x] += [s_1]
p[y] += [s_2]
p[x].remove(s_2)
p[y].remove(s_1)
c[x], c[y] = c[y], c[x]
return c, p
def anotherFunction():
iter = 1000
for i in iter:
c_main, p_main = temp(c, p)
I have a list of list with numbers ranging from 0 to n. For example c contains the following
c = [[7], [6], [1], [2], [5], [4], [0], [3]]
And p is also a list of list that contains all the numbers from 0 to n except that at index which are there in c.
p = [[0, 2, 4, 6, 5, 1, 3]
[0, 1, 2, 3, 4, 5, 7]
[0, 2, 3, 4, 6, 7, 5]
[0, 1, 3, 5, 6, 7, 4]
[0, 2, 4, 6, 7, 3, 1]
[0, 1, 2, 3, 6, 7, 5]
[1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 4, 5, 6, 7]]
This is how the values should be at any random point in the function. That is the values at idx in c should not be present in the list at idx in p.
But sometimes during the execution of the function, the values selected by x and y are swapped but one other value also gets affected. This is how the two list looks like sometimes
c = [[3], [1], [4], [5], [7], [0], [2], [6]]
p = [[0, 1, 2, 4, 5, 6, 7]
[0, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 6, 7, 4]
[0, 1, 2, 3, 6, 5, 5]
[0, 1, 2, 3, 4, 6, 7]
[1, 2, 3, 4, 6, 7, 5]
[0, 1, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 4, 5, 7]]
I'm unable to understand how these consecutive operations are getting affected by one another. This function gets called inside a loop of another function.
UPDATE:
I debugged my code more carefully and realized that at some iterations of the for loop two more values get swapped in c in addition to x and y. And because these values get swapped but they are not updated in p in some executions I get a faulty output. Any ideas why two more values are getting swapped.
Your code is not complete.
You seam to call your function like this:
c = [[3], [1], [4], [5], [7], [0], [2], [6]]
p = [[0, 1, 2, 4, 5, 6, 7],
[0, 2, 3, 4, 5, 6, 7],
[0, 1, 2, 3, 6, 7, 4],
[0, 1, 2, 3, 6, 5, 5],
[0, 1, 2, 3, 4, 6, 7],
[1, 2, 3, 4, 6, 7, 5],
[0, 1, 3, 4, 5, 6, 7],
[0, 1, 2, 3, 4, 5, 7]]
for i in range(1000):
c_main, p_main = temp(c, p)
note: if fixed your code: add range and add comma for each lines in p.
But inside your temp() function, your are modifying the content of p.
So, you may not have what you expect. Because you reuse the same p at each iteration. So sometimes it becomes inconsistent.
What you want, is certainly something like that:
import random
def temp(c):
# -- raw matrix
p = [[col for col in range(8)] for row in range(len(c))]
# -- drop a number
for p_row, c_row in zip(p, c):
p_row.pop(c_row[0])
# -- shuffle
for row in p:
random.shuffle(row)
return p
You can use it like this:
cols = [[3], [1], [4], [5], [7], [0], [2], [6]]
print(temp(cols))
You get:
[[6, 1, 4, 5, 7, 2, 0],
[3, 0, 5, 4, 2, 7, 6],
[2, 7, 0, 3, 6, 5, 1],
[1, 2, 7, 4, 6, 3, 0],
[3, 1, 4, 6, 2, 0, 5],
[4, 5, 6, 3, 7, 1, 2],
[0, 6, 1, 5, 7, 3, 4],
[4, 3, 7, 0, 1, 5, 2]]

Categories

Resources