Reputation: 8277
I am analysing data using Python and I have a list of N 2d data arrays. I would like to look at these elements one by one and compare them to the average of the other N-1 elements.
Is there a built-in method in Python to loop over a list and have on one hand a single element and on the other the rest of the list.
I know how to do it the ``ugly'' way by looping over an integer and joining the left and right part:
for i in xrange(N):
my_element = my_list[i]
my_sublist = my_list[:i] + my_list[i+1:]
but is there a Pythonista way of doing it?
Upvotes: 2
Views: 497
Reputation: 82889
I would like to look at these elements one by one and compare them to the average of the other N-1 elements.
For this specific use case, you should just calculate the sum of the entire list once and substract the current element to calculate the average, as explained in JuniorCompressor's answer.
Is there a built-in method in Python to loop over a list and have on one hand a single element and on the other the rest of the list.
For the more general problem, you could use collections.deque
to pop
the next element from the one end, giving you that element and the remaining elements from the list, and then add it back to the other end before the next iteration of the loop. Both operations are O(1).
my_queue = collections.deque(my_list)
for _ in enumerate(my_list):
my_element = my_queue.popleft() # pop next my_element
my_sublist = my_queue # rest of queue without my_element
print my_element, my_sublist # do stuff...
my_queue.append(my_element) # re-insert my_element
Sample output for my_list = range(5)
:
0 deque([1, 2, 3, 4])
1 deque([2, 3, 4, 0])
2 deque([3, 4, 0, 1])
3 deque([4, 0, 1, 2])
4 deque([0, 1, 2, 3])
Upvotes: 1
Reputation: 20005
We can calculate the sum of all elements. Then we can easily for each element find the sum of the rest of the elements. We subtract from the total sum the value of the current element and then in order to find the average we divide by N - 1
:
s = sum(my_list)
for my_element in my_list:
avg_of_others = (s - my_element) / float(len(my_list) - 1)
...
EDIT:
This is an example how it can be extended to numpy
:
import numpy as np
l = np.array([(1, 2), (1, 3)])
m = np.array([(3, 1), (2, 4)])
my_list = [l, m]
s = sum(my_list)
for my_element in my_list:
avg_of_others = (s - my_element) / float(len(my_list) - 1)
Upvotes: 3
Reputation: 15388
Nothing built-in that I know of, but maybe a little less copy-intensive using generators:
def iwithout(pos, seq):
for i, elem in enumerate(seq):
if i != pos:
yield elem
for elem, others in (elem, iwithout(i, N) for i, elem in enumerate(N)):
...
# others is now a generator expression running over N
# leaving out elem
Upvotes: 1