Learning is a mess
Learning is a mess

Reputation: 8277

Python split list by one element

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

Answers (3)

tobias_k
tobias_k

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

JuniorCompressor
JuniorCompressor

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

dhke
dhke

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

Related Questions