How to add value to particular part of python list? - python

NOTE: My need isn't this e.g. List[2:4] = 5
Suppose my List=[1,2,3,4,5,6]
I want to add 5 from index 2 to 4.
So the resultant List would be like List=[1,2,8,9,10,6]
If I have 2d array List=[[1,2,3],[4,5,6]] and want to add 5 to col 1 List=[[6,2,3],[9,5,6]]then what would be the code?

One approach is
my_list = [1,2,3,4,5]
add_item = [2,3]
new_list = [x+1 if i in add_item else x for i, x in enumerate(my_list)]
print(new_list)

This can be easily done through list comprehension.
The following function takes a 2D array 2d, a position index i and a value v, and adds v to the i-th element of each array.
def add_value(2d, i, v):
return [array[:i] + [array[i]+v] + array[i+1:] for array in 2d]
So, calling the function on the list in your example:
my_list = [[1,2,3],[4,5,6]]
add_value(my_list,0,5)
Would print out the desired output:
>>> [[6, 2, 3], [9, 5, 6]]

Numpy arrays can handle such slice operations:
import numpy as np
List = np.array([1, 2, 3, 4, 5, 6])
List[2:5] += 5
print(List)
Numpy will really come in handy for you if you have many of such tasks to do in your code. However, if it's just a one time thing in your code, you can do:
List = [1, 2, 3, 4, 5, 6]
for i in range(2, 5):
List[i] += 5
print(List)
Output:
[1, 2, 8, 9, 10, 6]
EDIT
Addressing your edit, you can also use numpy arrays like so:
import numpy as np
List = np.array([[1, 2, 3], [4, 5, 6]])
List[0] += 5
print(List)
Or using a loop:
List = [[1, 2, 3], [4, 5, 6]]
for i in range(len(List[0])):
List[0][i] += 5
print(List)
Output:
[[6, 7, 8], [4, 5, 6]]

One solution uses NumPy but my implementation is on an in-built list and other solutions are copying unnecessary elements.
So here I found the manual way to do it.
List = [[1,2,3,4,5],[6,7,8,9,10]]
# for horizontal update
colToUpdate = 2
for r in range(0,2):
A[r][colToUpdate] += add
# for vertical update
rowToUpdate = 1
for c in range(2,5):
A[rowToUpdate][c] += add

Related

How to get the get the lowest sum of 3 elements in matrix

A = [[1, 2, 4],
[3, 5, 6],
[7,8,9]]
def sumof(A,3):
We need to find the lowest sum of 3 elements
here 1 + 2 + 3 = 6 so output is (1,2,3)
Can we do by using zip
one basic solution, convert nested list into flat list, sort it,slice sorted list and sum:
A = [[1, 2, 4],
[3, 5, 6],
[7,8,9]]
def sumof(A, n):
# convert nested list into flat list
flat_list = [item for sublist in A for item in sublist]
return sum(sorted(flat_list)[:n])
print (sumof(A,3))
If you have a large array, you can do this without sorting the list,
which is a little faster like
from operator import add
from functools import reduce
A = [[1, 2, 4],
[3, 5, 6],
[7,8,9]]
addlists = lambda l: reduce(add, l)
list_A = addlists(A)
result = [list_A.pop(list_A.index(min(list_A))) for _ in range(3)]
It's a little more complicated, though the modules imported are really useful.

functions on arrays of different sizes in for loop

I have two arrays of different sizes that I want to perform logical functions on in a for loop. For example, if I have:
array1 = [6,7,8]
array2 = [1,2,3,4,5]
I want to do each element from array1 minus each element of array2 to get something like
[6-1,6-2,6-3,6-4,6-5],[7-1,7-2,7-3,7-4,7-5],[8-1,8-2,8-3,8-4,8-5]
which is subtracting each element from array2 from each element of array1
So i tried to do a for loop like:
for i in range(len(array1)):
ar = array1[i]-array2
and also
for i in range(len(array1)):
for j in range(len(array2)):
ar = array1[i]-array2[j]
But neither of these seem to be working
The first way seems to be returning an array of the right shape but certainly not the right values.
I'd like it to be returned in separate arrays because in reality, I have a very large sample size.
We can solve this using itertools.product
from itertools import product
from operator import sub
final = []
for item in array1:
prods = product([item], array2)
subs = [sub(*p) for p in prods]
final.append(subs)
print(final)
# [[5, 4, 3, 2, 1], [6, 5, 4, 3, 2], [7, 6, 5, 4, 3]]
How it works is product returns the cartesian product of the two arrays in the form of tuples, so:
(6, 1), (6, 2), etc....
Then we simply apply the sub function to each tuple using a list-comprehension.
The following solution should work using a list comprehension:
result = []
for value1 in array1:
result.append([value1 - value2 for value2 in array2])
You could even write this in 1 line using both for loops for the list comprehension:
result = [[value1 - value2 for value2 in array2] for value1 in array1]
Loops solution:
array1 = [6, 7, 8]
array2 = [1, 2, 3, 4, 5]
arr = []
for i in array1:
tmp = []
for j in array2:
tmp.append(i - j)
arr.append(tmp)
print(arr)
Output:
[[5, 4, 3, 2, 1], [6, 5, 4, 3, 2], [7, 6, 5, 4, 3]]
Your for loop is nearly correct except, you overwrite the value of ar every iteration (and you make it slightly more complicated with range)
You can achieve this through list comprehension
[[i - j for j in array2] for i in array1]
# [[5, 4, 3, 2, 1], [6, 5, 4, 3, 2], [7, 6, 5, 4, 3]]
You were on the right track but you had your arrays switched. You want array1 inside the inner loop to perform the operation you want to perform:
array1 = [6,7,8]
array2 = [1,2,3,4,5]
finalarray=[]
for i in range(len(array2)):
for j in range(len(array1)):
ar = array1[j]-array2[i]
finalarray.append(ar)
print(finalarray)
>>>[5, 6, 7, 4, 5, 6, 3, 4, 5, 2, 3, 4, 1, 2, 3]
ar is not being treated properly in your code, it needs to be an array of arrays (matrix) and you'll need another variable to hold the result per iteration, there's probably a better way to do this using list comprehensions but here is one way:
array1 = [6,7,8]
array2 = [1,2,3,4,5]
ar = []
row = []
for i in range(len(array1)):
for j in range(len(array2)):
row.append(array1[i]-array2[j])
ar.append(row)
row = []
print ar
There are plenty of good answers here, but another option especially useful for larger arrays is to use numpy, a package designed for moving large arrays of numbers efficiently. One possible answer in numpy would be this:
import numpy as np
array1 = np.arange(6,9) # make arrays 1 and 2
array2 = np.arange(1,6)
output = (array1.repeat(array2.shape[0]) # repeat array1 as many times as there are elements in array2
.reshape(array1.shape[0], -1) # reshape so we have a row for each element in array1
) - array2 # subtract array2 from each row
output
array([[5, 4, 3, 2, 1],
[6, 5, 4, 3, 2],
[7, 6, 5, 4, 3]])

I need to create a list containing all the sums of a list taken three at a time, ie, add first 3 elements then the next 3 [duplicate]

This question already has answers here:
How do I split a list into equally-sized chunks?
(66 answers)
Closed 6 years ago.
I need to add the first three elements of a list then add the next three elements of a list and so forth. This is the code I have got so far:
def get_triple_sums_list(a_list):
new_list = []
for numbers in range(0,len(a_list)):
numbers = sum(a_list[:3])
new_list.append(numbers)
return new_list
if a_list == []:
return []
For the list:
[1, 5, 3, 4, 5, 2]
This in turn gives me the result:
[9]
I need to get
[9, 11]
If the remaining numbers is less than 3, it gives me the remainder of the sum ie,
[1, 6, 2, 4, 3]
Gives me
[9, 7]
And
[1, 6, 2, 4]
Give me
[9, 4]
Let's analyze your code!
def get_triple_sums_list(a_list):
new_list = []
for numbers in range(0,len(a_list)):
numbers = sum(a_list[:3]) #You should be using the variable
#numbers here somehow.
#^^^^^^^ - You are overwriting the for-loop index.
new_list.append(numbers)
return new_list #Why are you returning here? You should be
#appending to `new_list`.
if a_list == []:
return []
Here is the fixed code:
def get_triple_sums_list(a_list):
new_list = []
for index in range(0,len(a_list), 3): #Range takes a 3rd param!
total = sum(a_list[index:index+3])#Get all the elements from the
#index to index+3
new_list.append(total)
return new_list
UPDATE: It seems there's a shortening contest going on -- and I do not want to be left behind. Here's an ugly version I'd like to add to the list.
>>> a = [1,2,3,4,5,6,7,8]
>>> a += [0]*(len(a)%3) #For people who are too lazy to import izip_longest
>>> map(sum,zip(a[::3], a[1::3], a[2::3]))
[6, 15, 15]
I like SuperSaiyan's approach of explaining things, I'll be the one who shortens it a bit. You can get the same result with a single comprehension:
l = [1, 5, 3, 4, 5, 2]
n = 3
r = [sum(l[i:i+n]) for i in range(0, len(l), n)]
print(r)
[9, 11]
l[i:i+n] splits the list in even chunks of length 3 and sum takes care of adding these together. Using the for i in range(0, len(l), n) we dictate that this operation is to happen for ceil(len(l) / 3) times.
Just cuz I like to be different.
l = [1, 5, 3, 4, 5, 3, 42]
g = lambda l,s: [sum(l[i:i+s]) for i in range(0,len(l),s)]
print g(l,3)
#>> [9,12,42]
The other answer mentions the fault with your code. However do note that it's always easier to use a list comprehension in these cases.
>>> l = [1, 5, 3, 4, 5, 2]
>>> [sum(l[i:i+3]) for i in range(0,len(l),3)]
[9, 11]
It also works for un-mod-3 lists
>>> l = [1, 5, 3, 4, 5]
>>> [sum(l[i:i+3]) for i in range(0,len(l),3)]
[9, 9]
See What does "list comprehension" mean? How does it work and how can I use it? for more details about a list comprehension.
Here is a slightly different way of doing it using zip_longest from itertools (izip_longest in python2), it splits the list in three lists then zip them to get packs of three elements and finally sums the packs:
from itertools import zip_longest
a=[1, 6, 2, 4, 3]
b=zip_longest(a[0::3],a[1::3],a[2::3],fillvalue=0)
result=[sum(x) for x in b]
>>>[9, 7]
Alternatively, you may achieve it by using map() with lambda function as:
>>> my_list = [1, 5, 3, 4, 5, 2]
>>> list(map(lambda x: sum(my_list[x:x+3]), range(0, len(my_list), 3)))
[9, 11]

How can I find same values in a list and group together a new list?

From this list:
N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
I'm trying to create:
L = [[1],[2,2],[3,3,3],[4,4,4,4],[5,5,5,5,5]]
Any value which is found to be the same is grouped into it's own sublist.
Here is my attempt so far, I'm thinking I should use a while loop?
global n
n = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5] #Sorted list
l = [] #Empty list to append values to
def compare(val):
""" This function receives index values
from the n list (n[0] etc) """
global valin
valin = val
global count
count = 0
for i in xrange(len(n)):
if valin == n[count]: # If the input value i.e. n[x] == n[iteration]
temp = valin, n[count]
l.append(temp) #append the values to a new list
count +=1
else:
count +=1
for x in xrange (len(n)):
compare(n[x]) #pass the n[x] to compare function
Use itertools.groupby:
from itertools import groupby
N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
print([list(j) for i, j in groupby(N)])
Output:
[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]
Side note: Prevent from using global variable when you don't need to.
Someone mentions for N=[1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 1] it will get [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5], [1]]
In other words, when numbers of the list isn't in order or it is a mess list, it's not available.
So I have better answer to solve this problem.
from collections import Counter
N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
C = Counter(N)
print [ [k,]*v for k,v in C.items()]
You can use itertools.groupby along with a list comprehension
>>> l = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
>>> [list(v) for k,v in itertools.groupby(l)]
[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]
This can be assigned to the variable L as in
L = [list(v) for k,v in itertools.groupby(l)]
You're overcomplicating this.
What you want to do is: for each value, if it's the same as the last value, just append it to the list of last values; otherwise, create a new list. You can translate that English directly to Python:
new_list = []
for value in old_list:
if new_list and new_list[-1][0] == value:
new_list[-1].append(value)
else:
new_list.append([value])
There are even simpler ways to do this if you're willing to get a bit more abstract, e.g., by using the grouping functions in itertools. But this should be easy to understand.
If you really need to do this with a while loop, you can translate any for loop into a while loop like this:
for value in iterable:
do_stuff(value)
iterator = iter(iterable)
while True:
try:
value = next(iterator)
except StopIteration:
break
do_stuff(value)
Or, if you know the iterable is a sequence, you can use a slightly simpler while loop:
index = 0
while index < len(sequence):
value = sequence[index]
do_stuff(value)
index += 1
But both of these make your code less readable, less Pythonic, more complicated, less efficient, easier to get wrong, etc.
You can do that using numpy too:
import numpy as np
N = np.array([1,2,2,3,3,3,4,4,4,4,5,5,5,5,5])
counter = np.arange(1, np.alen(N))
L = np.split(N, counter[N[1:]!=N[:-1]])
The advantage of this method is when you have another list which is related to N and you want to split it in the same way.
Another slightly different solution that doesn't rely on itertools:
#!/usr/bin/env python
def group(items):
"""
groups a sorted list of integers into sublists based on the integer key
"""
if len(items) == 0:
return []
grouped_items = []
prev_item, rest_items = items[0], items[1:]
subgroup = [prev_item]
for item in rest_items:
if item != prev_item:
grouped_items.append(subgroup)
subgroup = []
subgroup.append(item)
prev_item = item
grouped_items.append(subgroup)
return grouped_items
print group([1,2,2,3,3,3,4,4,4,4,5,5,5,5,5])
# [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]

Python weave lists

I want to "weave" two numberrows together.
Example:
x = [1,2,3]
y = [4,5,6]
result = [1,4,2,5,3,6]
This is my function, I can't find out why it doesn't work:
def weave(list1,list2):
lijst = []
i = 0
for i <= len(list1):
lijst += [list1[i]]
lijst += [list2[i]]
i + 1
You can use the chain function from itertools module to interleave two lists:
x = [1,2,3]
y = [4,5,6]
from itertools import chain
list(chain.from_iterable(zip(x, y)))
# [1, 4, 2, 5, 3, 6]
Python's for-loops aren't like other languages where you can have a conditional. You need to use a while loop instead or alter your for-loop:
def weave(list1,list2):
lijst = []
i = 0
while i < len(list1):
lijst.append(list1[i])
lijst.append(list2[i])
i += 1
return lijst
I've altered your code in a variety of ways:
Use a while loop if you have a condition you want to loop through
You want the conditional to be less than the length, not less than or equal to. This is because indexing starts at 0, and if you do <=, then it will try to do list1[3] which is out of bounds.
Use list.append to add items to list
You forgot the = in i += 1
Finally, don't forget to return the list!
You could also use zip():
>>> [a for b in zip(x, y) for a in b]
[1, 4, 2, 5, 3, 6]
You can also weave lists by defining the even and odd half-lists of the result list.
x = [1,2,3]
y = [4,5,6]
z = numpy.empty(len(x)+len(y))
z[::2],z[1::2]=x,y
result=z.tolist()
You need to append list item at every iteration so use list.append and in python you don't need to initialise i =0.
try this:-
>>> a = [1,2 ,3]
>>> b = [4, 5, 6]
>>> list(chain.from_iterable(zip(a, b)))
[1, 4, 2, 5, 3, 6]
You can play with this script:
reduce(lambda a, b: a+b, zip([1, 2, 3], [4, 5, 6]), ())
Notes:
zip will make pairs, add will join them;
you can use operator.add instead of lambda;
itertools.izip can be used if lengths of lists are different.
>>> x = [1,2,3]
>>> y = [4,5,6]
>>> z=[]
>>> for i,j in zip(x,y):
... z.extend([i,j])
...
>>> z
[1, 4, 2, 5, 3, 6]
I needed this, but with an arbitrary number of lists of potentially different lengths, which some of the other more elegant answers do not offer. Here is a simple implementation with no dependencies:
def weave_lists(list_of_lists):
max_index = max([len(sublist) for sublist in list_of_lists])
weaved_list = []
for sublist_index in range(max_index):
for sublist in list_of_lists:
if len(sublist) > sublist_index:
weaved_list.append(sublist[sublist_index])
return weaved_list
print(weave_lists([[1,2], [3,4,5], [6,7,8,9]]))
# [1, 3, 6, 2, 4, 7, 5, 8, 9]
x = [1,2,3]
y = [4,5,6]
As mentioned by others (and is the clearest as well as the way I'd do it since it since its the most understandable given the semantics of chain), You can do this by using itertools:
from itertools import chain
list(chain.from_iterable(zip(x, y)))
[1, 4, 2, 5, 3, 6]
However you could also use tuple summing up (concatenation) by:
list(sum(zip(x,y), ()))
[1, 4, 2, 5, 3, 6]

Categories

Resources