how to increase list valuesby list average value - python

I want to increase my values in list by average value of list.
lista1 = [2,3,4,5,6]
dlugoscListy = len(lista1)
sumaListy = sum(lista1)
srednia = sumaListy / dlugoscListy
lista2 = [i for i in lista1 += srednia]
print(lista2)
My code looks like above, but it is not working

The syntax in your list comprehension is wrong. It needs to look like this:
list2 = [element + list_avg for element in my_list]
The expression has to be at the start, not the end.
Also you shouldn't use i in this case, as you are not counting numbers in a range, but using a for _ in loop and dealing with actual values from the list. You should call it "element" or "value" instead. This can easily lead to confusion, especially if you deal with lists which contain numbers, like in your case.

The numpy library can also do it very well (and fast).
import numpy as np
lista1 = np.array([2, 3, 4, 5, 6])
lista2 = lista1 + np.mean(lista1)
print(lista2)

Related

Excluding elements from an old array and creating a new array

I have an array that has 3 different values, I want to create a new array that has only the values that are smaller that 12 (for example).
import array as arr
numbers = arr.array([10,12, 12, 13])
numbers.remove(12)
numbers.remove(13)
print(numbers)
I don't know how to add them in a new array
There are a few ways to solve this problem. Here's how I would go about it.
import array as arr
numbers = arr.array('i', [10,12,12,13])
new_nums = arr.array('i', [i for i in numbers if i<12])
You can also use the pop() method, like so:
new_nums = arr.array('i', [numbers.pop(i) for i,val in enumerate(numbers) if val<12])
Alternatively, you can just use list comprehension on a Python list, like this:
new_nums = [i for i in numbers if i<12]
Hope this helps!
numbers = [10,12,13,14]
newarr = []
for i in numbers:
if i<12:
newarr.append(i)
print(newarr)
Use a python list and iterate over the previous list(Use list, not an array), check for the required condition and add(append) the results to a new list.
Assumption:
you want only unique elements from the initial list
the elements should be less than 12
Code:
initial_list = [10, 12, 12, 13]
new_list = [i for i in list(set(initial_list)) if i<12]
print(new_list)
Output:
[10]
Explanation:
The above code first creates a set of unique elements from the initial list. Then it selects the only items that meet the condition i<12 using a list comprehension.
N.B.: If you are bound to use array module, #Praveenkumar's answer is the way to use.
You can do the below if you want to stick with array only (I don't know why you want to do that). array and list in python are different things.
import array as arr
numbers = arr.array('i', [10,11, 12, 13])
print(arr.array('i', filter(lambda x : x < 12, numbers)))

Randomly remove 'x' elements from a list

I'd like to randomly remove a fraction of elements from a list without changing the order of the list.
Say I had some data and I wanted to remove 1/4 of them:
data = [1,2,3,4,5,6,7,8,9,10]
n = len(data) / 4
I'm thinking I need a loop to run through the data and delete a random element 'n' times? So something like:
for i in xrange(n):
random = np.randint(1,len(data))
del data[random]
My question is, is this the most 'pythonic' way of doing this? My list will be ~5000 elements long and I want to do this multiple times with different values of 'n'.
Thanks!
Sequential deleting is a bad idea since deletion in a list is O(n). Instead do something like this:
def delete_rand_items(items,n):
to_delete = set(random.sample(range(len(items)),n))
return [x for i,x in enumerate(items) if not i in to_delete]
You can use random.sample like this:
import random
a = [1,2,3,4,5,6,7,8,9,10]
no_elements_to_delete = len(a) // 4
no_elements_to_keep = len(a) - no_elements_to_delete
b = set(random.sample(a, no_elements_to_keep)) # the `if i in b` on the next line would benefit from b being a set for large lists
b = [i for i in a if i in b] # you need this to restore the order
print(len(a)) # 10
print(b) # [1, 2, 3, 4, 5, 8, 9, 10]
print(len(b)) # 8
Two notes on the above.
You are not modifying the original list in place but you could.
You are not actually deleting elements but rather keeping elements but it is the same thing (you just have to adjust the ratios)
The drawback is the list-comprehension that restores the order of the elements
As #koalo says in the comments the above will not work properly if the elements in the original list are not unique. I could easily fix that but then my answer would be identical to the one posted by#JohnColeman. So if that might be the case just use his instead.
Is the order meaningful?
if not you can do something like:
shuffle(data)
data=data[:len(data)-n]
I suggest using numpy indexing as in
import numpy as np
data = np.array([1,2,3,4,5,6,7,8,9,10])
n = len(data)/4
indices = sorted(np.random.choice(len(data),len(data)-n,replace=False))
result = data[indices]
I think it will be more convenient this way:
import random
n = round(len(data) *0.3)
for i in range(n):
data.pop(random.randrange(len(data)))

Enumerate list to make a new list of indices?

I'm trying to make a new list of indices by enumerated a previous list. Basically, what I want is:
To enumerate a list of elements to obtain indices for each element. I coded this:
board = ["O","O","O","O","O"]
for index,y in enumerate(board):
print(index,end=" ")
which gives:
0 1 2 3 4
I now want to make those numbers into a new list, but have no clue how to do that.
Thanks! Sorry for the question, I'm still a beginner and am just trying to get the hang of things.
You should probably just make a range of the right length:
board = ["O","O","O","O","O"]
indices = list(range(len(board)))
print(indices)
> [0, 1, 2, 3, 4]
Use list comprehension:
indices = [index for index, y in enumerate(board)]
If board is always a object, which implements the __len__-method, you can also use range:
indices = list(range(len(board)))
If you just want all the numbers you can use this:
indices = list(range(len(board)))
If you pass one number to range it will return an iterator with the numbers 0 up to the passed number (excluding). After this we turn it into a list with the list function.
You can use list comprehension to do that:
result = [index for index,y in enumerate(board)]
Alternatively you can use the range function:
result = range(len(board))
I would just use numpy arange, which creates an array that looks like the one you are looking for:
Numpy Arange
import numpy as np
enumerated = np.arange(len(board))
The straightforward way is:
board = ["O","O","O","O","O"]
newlist = []
for index,y in enumerate(board):
newlist.append(index)
A more advanced way using list comprehensions would be:
newlist = [index for index, value in enumerate(board)]

How to traverse a list in reverse order in Python (index-style: '... in range(...)' only)

I'm new to Python so I am still getting used to looping in this language.
So, for example, I have the following code (the element type in the list is array)
my_list = [array0, array1, array2, array3]
temp = my_list[-1]
for k in range(len(my_list) - 1, 0):
temp = temp + my_list[k - 1]
return temp
I want to traverse the list from the end of the list and stop at the second element (k=1), but it looks like the for loop will never be entered and it will just return the initial temp outside the loop. I don't know why. Can someone help? Thanks.
Avoid looping with range, just iterate with a for loop as a general advice.
If you want to reverse a list, use reversed(my_list).
So in your case the solution would be:
my_list = reversed([array0,array1,array2,array3])
That gives you [array3, array2, ...]
For omitting the last array from the reversed list, use slicing:
my_list = reversed([array0,array1,array2,array3])[:-1]
So your code turns to a one liner :-)
Let's look at this part by part:
len(my_list) is 4. Thus range(len(my_list)-1, 0) is the same as range(3, 0), which is [] in Python 2. (In Python 3, try list(range(3, 0)) to see the same empty list.)
If you want a declining range, use a negative step (third argument):
range(3, 0, -1)
gives [3, 2, 1]. It doesn't include 0, because even for negative steps, the upper bound (second argument) is exclusive, i.e., not part of the result. It seems you've worked around this by initializing the temp variable with the last array in my_list already before then loop, and then subtracting 1 from the index when using it to access my_list contents in the loop.
my_list = [array0, array1, array2, array3]
temp = my_list[-1]
for k in range(len(my_list) - 1, 0, -1):
temp = temp + my_list[k - 1]
return temp
would thus probably work.
However, if you need the indices only to access my_list, you can get rid of them by directly iterating over the elements of my_list in the (here reverse) order you want:
my_list = [array0, array1, array2, array3]
temp = empty_array # Not quite sure what this has to be. (Depends on your array type.)
for array in reversed(my_list):
temp = temp + array
return temp
I'm assuming your arrays are concatenated in the loop. If it's instead an actual addition (NumPy vector addition, for example — though I don't see why the order of addition would matter for that, except maybe for precision, if the values in my_list are sorted), use an appropriate zero-element instead of empty_array.
You can even get rid of the loop completely. If you want to add your arrays:
my_list = [array0, array1, array2, array3]
return sum(reversed(my_list))
If you want to concatenate them:
from itertools import chain
my_list = [array0, array1, array2, array3]
return list(chain.from_iterable(reversed(my_list)))
You can traverse a list in reverse like so:
for i in range(len(lis), 0, -1):
print (i)
To stop at the second element edit your range() function to stop at 1:
for i in range(len(lis), 1, -1):
print (i)

Basic python: how to increase value of item in list [duplicate]

This question already has answers here:
Why does this iterative list-growing code give IndexError: list assignment index out of range? How can I repeatedly add (append) elements to a list?
(9 answers)
Closed 4 months ago.
This is such a simple issue that I don't know what I'm doing wrong. Basically I want to iterate through the items in an empty list and increase each one according to some criteria. This is an example of what I'm trying to do:
list1 = []
for i in range(5):
list1[i] = list1[i] + 2*i
This fails with an list index out of range error and I'm stuck. The expected result (what I'm aiming at) would be a list with values:
[0, 2, 4, 6, 8]
Just to be more clear: I'm not after producing that particular list. The question is about how can I modify items of an empty list in a recursive way. As gnibbler showed below, initializing the list was the answer. Cheers.
Ruby (for example) lets you assign items beyond the end of the list. Python doesn't - you would have to initialise list1 like this
list1 = [0] * 5
So when doing this you are actually using i so you can just do your math to i and just set it to do that. there is no need to try and do the math to what is going to be in the list when you already have i. So just do list comprehension:
list1 = [2*i for i in range(5)]
Since you say that it is more complex, just don't use list comprehension, edit your for loop as such:
for i in range(5):
x = 2*i
list1[i] = x
This way you can keep doing things until you finally have the outcome you want, store it in a variable, and set it accordingly! You could also do list1.append(x), which I actually prefer because it will work with any list even if it's not in order like a list made with range
Edit: Since you want to be able to manipulate the array like you do, I would suggest using numpy! There is this great thing called vectorize so you can actually apply a function to a 1D array:
import numpy as np
list1 = range(5)
def my_func(x):
y = x * 2
vfunc = np.vectorize(my_func)
vfunc(list1)
>>> array([0, 2, 4, 6, 8])
I would advise only using this for more complex functions, because you can use numpy broadcasting for easy things like multiplying by two.
Your list is empty, so when you try to read an element of the list (right hand side of this line)
list1[i] = list1[i] + 2*i
it doesn't exist, so you get the error message.
You may also wish to consider using numpy. The multiplication operation is overloaded to be performed on each element of the array. Depending on the size of your list and the operations you plan to perform on it, using numpy very well may be the most efficient approach.
Example:
>>> import numpy
>>> 2 * numpy.arange(5)
array([0, 2, 4, 6, 8])
I would instead write
for i in range(5):
list1.append(2*i)
Yet another way to do this is to use the append method on your list. The reason you're getting an out of range error is because you're saying:
list1 = []
list1.__getitem__(0)
and then manipulate this item, BUT that item does not exist since your made an empty list.
Proof of concept:
list1 = []
list1[1]
IndexError: list index out of range
We can, however, append new stuff to this list like so:
list1 = []
for i in range(5):
list1.append(i * 2)

Categories

Resources