Ssylvia
Ssylvia

Reputation: 23

How to systematically compare one number in a list to the rest of the list [Python]

For a given item in a list, I want to compare that item to each subsequent item (let's call it item[i]). If item > item[i], I want to add 1 to P. If item < item[i], I want to add 1 to Q. I don't want to compare item to anything that came before it in the list, however.

I've explored a few possibilities to achieve this, but I haven't quite cracked it. One option was to try enumerating the list and referring to each item's "count" in the list. The one that seems like it makes the most sense to me is to just refer to the index of each item in the list. However, as I don't want to just compare each item solely to the next item in the list, but rather all subsequent items, I need to compare item to a range of indices, starting at the index of the item + 1.

Below I've written a simple for loop, but it of course doesn't work because the [f::] yields a

The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

error.

Thoughts on this are welcome!

b_rank = [2.0, 3.0, 1.0, 6.0, 4.0, 5.0]

for y in b_rank:
    f = b_rank.index(y)
    while f < len(b_rank):
        if b_rank[f] > b_rank[f::]:
            P += 1
        elif b_rank[f] < b_rank[f::]:
            Q += 1

Upvotes: 2

Views: 1072

Answers (3)

Ben
Ben

Reputation: 6348

Here are two approaches.

b_rank = [2.0, 3.0, 1.0, 6.0, 4.0, 5.0]

p = 0
q = 0

for index, item in enumerate(b_rank):
    # Note: creating a copy of the list by slicing like this is inefficient
    # if the list is huge
    for following_item in b_rank[index + 1:]:
        if item > following_item:
            p += 1
        if item < following_item:
            q += 1
print(p, q)

If you need efficiency, it's a little more work (thanks @MoxieBall !):

import itertools

b_rank = [2.0, 3.0, 1.0, 6.0, 4.0, 5.0]

p = 0
q = 0

for index, item in enumerate(b_rank):
    # https://docs.python.org/3/library/itertools.html#itertools.islice
    for following_item in itertools.islice(b_rank, index + 1, None):
        if item > following_item:
            p += 1
        if item < following_item:
            q += 1

print(p, q)

Also, please add code to cover the case where item == following_item

Upvotes: 1

A_K
A_K

Reputation: 457

Try:

for idx_y, y in enumerate(b_rank):
    f = idx_y + 1
    while f < len(b_rank):
        if b_rank[f] > b_rank[idx_y]:
            P += 1
        elif b_rank[f] < b_rank[idx_y]:
            Q += 1
        f += 1

Upvotes: 0

MoxieBall
MoxieBall

Reputation: 1916

Though that is a numpy error message, so I expect that something else is going on, here is how you would do this in pure python:

for i, e in enumerate(b_rank):
    for f in b_rank[i+1:]:
        if e > f:
            P += 1
        elif e < f:
            Q += 1

Upvotes: 1

Related Questions