How to sum up individual nested lists in python - python

data = [[1, 1, 0, 1, 1, 0, 0], [0, 0, 1, 0, 0, 1, 0], [0, 0, 1, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 2, 3], [1, 1, 2, 0, 1, 1, 0], [1, 0, 0, 2, 1, 1, 2]]
Hello, I have this list with nested lists called data. I would like to sum up the indivual nested lists only so the output is:
[[4],[2],[2],[0],[0],[0],[0],[0],[6],[6],[7]]
I tried to do this:
for numbers in data:
new_list = []
y = sum(numbers)
new_list.append(y)
print (new_list)
However, this only gives the sum of the last nested list, because for every for-loop the new_list seems to "reset".
Thanks

Not sure why you would want each sum to be a single element list but you can do it in a list comprehension:
[ [sum(sl)] for sl in data ]
[[4], [2], [2], [0], [0], [0], [0], [0], [6], [6], [7]]

The reason is that your new_list must be outside of the loop. Right now, after each iteration, you are overwriting your new_list. Also, if you want each element to be a list you will need to change to [y] Try to:
new_list = []
for numbers in data:
y = sum(numbers)
new_list.append([y])
print (new_list)
Also, if you want to use python's list comprehension feature you can do:
new_list = [[sum(numbers)] for numbers in data]

Related

How can i group and sum elements in matrix, without using itertools.groupby?

the problem that I am facing is simple. I have matrix as list of lists like this:
[[0, 0, 1, 0, 0, 0, 0], [0, 1, 0, 1, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1], [0, 0, 1, 1, 0, 0, 1], [0, 0, 0, 1, 1, 1, 0], [0, 0, 1, 0, 1, 0, 0]]
And I want to get is tuple that has grouped occurrences of 1 for rows on one side and for cols on the other. So for the matrix above it would be like this:
([[1], [1, 1, 1], [7], [2, 1], [3], [1, 1]],[[1], [2], [1, 2, 1], [4], [1, 2], [1, 1], [3]])
As you can see it "sums" adjascent duplicates so list like this [1,0,1,1] would resolve in [[1],[0],[2]]
I tried working on the rows and ended up with this:
for line in matrix:
new_list = []
for value in line:
if new_list and new_list[-1][0] == value:
new_list[-1].append(value)
else:
new_list.append([value])
result_list.append(new_list)
This splits the list into duplicates but does not sum the adjascent and still leaves 0 in the result.
Does anyone have good solution for both rows and colls to achieve my desired Tuple?
PS: I know i could use itertools.groupby but I am trying to solve it without it.
Assuming your data is in data, here you go:
def grp(data):
result = []
for row in data:
count = 0
row_result = []
for c in row:
if c==0:
if count > 0:
row_result.append(count)
count = 0
else:
count += 1
if count > 0:
row_result.append(count)
result.append(row_result)
return result
data = [[0, 0, 1, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1],
[0, 0, 1, 1, 0, 0, 1],
[0, 0, 0, 1, 1, 1, 0],
[0, 0, 1, 0, 1, 0, 0]]
print((grp(data),grp(zip(*data)))
gives me your desired result (using Python 3).

How to remove brackets and content from a list in Python

So I have a list from which i want to remove something like a sub list. I don't know how to call it exactly so i couldn't find any results searching for an answer.
list = [[0, 1, 0, 0], [0, 1, 1, 1], [1, 1, 0, 0], [0, 0, 0, 0]]
I just want to remove one of those 4 brackets, for example the first one.
Should i use "remove" or "delete" or how do i do that?
list = [[0, 1, 1, 1], [1, 1, 0, 0], [0, 0, 0, 0]]
You can del it by its index. For example to delete the first one, you can do:
my_list = [[0, 1, 0, 0], [0, 1, 1, 1], [1, 1, 0, 0], [0, 0, 0, 0]]
del my_list[0]
print(my_list)
# output:
[[0, 1, 1, 1], [1, 1, 0, 0], [0, 0, 0, 0]]
If you know the index which you want to remove i:
del l[i]
# Or l.pop(i)
If you know the value you want to remove val:
l.remove(val)
P.S: Don't use list as the name of a variable. It's a name of a builtin class

Best way to assign list values to a 2D list

What is the best way to assign a list of value to a 2D list with different indices?
temp_list = [2, 1, 1, 5]
I want to iterate thru a 2D list:
list_to_assign =
[[0, 0, 0, 0],
[0, 0, 0, 0],
[2, 0, 0, 1000],
[0, 0, 0, 0]]
For every value of temp_list, I want to assign that value to the zero index of every inner list in the 2D list.
My desired result is
[[2, 0, 0, 0],
[1, 0, 0, 0],
[1, 0, 0, 1000],
[5, 0, 0, 0]]
IIUC, try using this list comprehension below:
print([[x] + y[1:] for x,y in zip(temp_list,list_to_assign)])
Output:
[[2, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 1000], [5, 0, 0, 0]]
for i in range(len(temp_list)):
list_to_assign[i][0] = temp_list[i]

if I have lists for the values in a dictionary, can I perform a conditional zip on these value lists?

I have the following dict that I created :
dct = {'T': [[1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 0, 1, 0]], 'B': [[0, 1, 0, 0, 0], [0, 0, 0, 0, 1]], 'J': [[0, 0, 1, 0, 0], [0, 0, 0, 0, 1]], 'K': [0, 0, 0, 0, 1]}
Note that each value is either a single list or multiple lists. I am trying to figure out if I can do a conditional zip on the value lists for each key (or some alternative solution that gives me my desired output). The condition is that I only want the value lists to zip together for a given key if the 1s on consecutive value lists are within a distance of 2 index values from each other.
The final output I want from this input dict should look like this:
zp_dict = {'T': [2, 1, 0, 1, 0], 'B': [[0, 1, 0, 0, 0], [0, 1, 0, 0, 0]], 'J': [0, 0, 1, 0, 1], 'K': [0, 0, 0, 0, 1]}
Notice that the value lists for 'T' and 'J' should be zipped together because the non-zero values are no more than 2 indices apart, but the value lists for 'B' should be kept separate because the non-zero values are 3 indices apart, and the 'K' value list should be left alone.
To illustrate what I'm trying to do, consider the following code that almost does what I want to do, but without the condition:
zp_dict = {}
for k, v in dct.items():
zp_dict[k] = [sum(x) for x in zip(*v)]
This produces the following new dict, which is wrong for key 'B':
zp_dict = { 'T': [2, 1, 0, 1, 0], 'B': [0, 1, 0, 0, 1], 'J': [0, 0, 1, 0, 1], 'K': [0, 0, 0, 0, 1]}
This technically achieves the result you are asking for. However, I am assuming you want everything to be added together if at least 2 of the lists have numbers within 2 indexes of each other. For example [[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 0, 0, 1]] would result in [1, 1, 0, 0, 1] NOT [[1, 1, 0, 0, 0], [0, 0, 0, 0, 1]] despite the last list having its number more than 2 indexes away from any other list.
The code sums the lists together, then finds how far apart the first 2 non-zero number are. If they are <= 2 indexes apart, then the summed list is added to zp_dict, else the list of lists (v) remains unchanged, and added to the zp_dict
The code is on OnlineGDB, if you want to tinker with it
Note: I assumed 'K' in the dct you provided had a typo, in that it was supposed to be a list within a list (like the others) - if not, sum(x) for x in zip(*v) would break. If not, it doesn't take much to fix - just validate the number of lists in v.
dct = {
'T': [[1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 0, 1, 0]],
'B': [[0, 1, 0, 0, 0], [0, 0, 0, 0, 1]],
'J': [[0, 0, 1, 0, 0], [0, 0, 0, 0, 1]],
'K': [[0, 0, 0, 0, 1]]
}
zp_dict = {}
for k, v in dct.items():
sum_list = [sum(x) for x in zip(*v)]
first_non_zero = next((i for i, n in enumerate(sum_list) if n), 0)
second_non_zero = next((i for i, n in enumerate(sum_list[first_non_zero+1:]) if n), 0)
zp_dict[k] = sum_list if second_non_zero < 2 else v
print(zp_dict)
>>{'T': [2, 1, 0, 1, 0], 'B': [[0, 1, 0, 0, 0], [0, 0, 0, 0, 1]], 'J': [0, 0, 1, 0, 1], 'K',: [0, 0, 0, 0, 1]}
EDIT:
You can also add if statements (with functions inline), if that is what you were looking for.
zp_dict[k] = [sum(x) for x in zip(*v) if conditionTest(v)]
If the conditionTest returns True, it would add the lists together. Although if you were fine with adding functions, I would clean it up and just add the for loop into the function:
zp_dict[k] = sumFunction(v)

How can I increment only the first element of the first row of a Python list of lists? [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 7 years ago.
s is a list of lists of integers with all values initialized to zero. I would like to increment only the first element of the first row by one, but the following command increments the first element of every row by one. How may I achieve this?
In [6]: s = [[0]*4]*4
In [7]: s[0][0] += 1
In [8]: s
Out[8]:
[[1, 0, 0, 0, 0],
[1, 0, 0, 0, 0],
[1, 0, 0, 0, 0],
[1, 0, 0, 0, 0],
[1, 0, 0, 0, 0]]
Okay! Thanks for the advice, the problem was in my construction of s.
If s is truly a list of lists (and not a list containing multiple references to the same list), what you did works, your issue must be elsewhere
>>> s = [[0, 0, 0, 0, 0],
... [0, 0, 0, 0, 0],
... [0, 0, 0, 0, 0],
... [0, 0, 0, 0, 0],
... [0, 0, 0, 0, 0]]
>>> s[0][0]
0
>>> s[0][0] = 1
>>> s
[[1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
You made your lists "incorrectly" in the first place; each element of your list simply points to the same single list. When you update that list they all update.
Make the list of lists using code something like this instead:
s = [[0 for _ in range(5)] for _ in range(5)]
This is classical Python oversight since lists assignments are done by references not by deep copy.
For example if you constructed using this way that's where it would have gone wrong.
>>> zeros = [0,0,0,0]
>>> s = [zeros,zeros,zeros,zeros]
>>> s[0][0]+=1
>>> s
[[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]]
So while copying lists use as below
>>> s = [list(zeros), list(zeros), list(zeros), list(zeros)]
>>> s[0][0]+=1
>>> s
[[1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

Categories

Resources