简体   繁体   中英

How to count items in a conditional loop using enumerate? Python

I have list of lists a containing 7 lists, and a list of lists x containing 2 lists. I want to test the lists in a against those in x .

My goal is to make an item-by-item comparison and find out for how many lists in a all values are larger than the corresponding item in x .

A condition and a counter check whether the a's touch the x's. Note: I am not interested in counting how many items in with a list, a1 for example, touch x1. Once a1 and x1 touch, I count that and can move on to a2, and so on.

However, the counter does not properly update. Any suggestions on how to solve this? Here is my code. The results I expect are shown below the code.

EDIT

To clarify the expected result, I have updated the example by adding a second value to x . So have updated from x = [[10], [14]] to x = [[10, 11], [14, 12]]

This is updated below.

x = [[10, 11], [14, 12]]
a = [[9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16]]

def touch(e, f):
    e = np.array(e)
    f = np.array(f)
    count = []
    counter = 0
    for i, lst in enumerate(e):
        if np.all(f > lst): # This is the condition
            counter += 0 # Counts violations of the condition
            count.append(counter)
            if i == 1:
                counter = 0
        else:
            counter += 1 # Counts violations of the condition
            print(counter)
            count.append(counter)
            if i == 1:
                counter = 0
    return count

touching = touch(x, a)
print(touching)

The result I expect is this:

[2, 6]

But I get this:

[1, 2]

EDIT

To clarify the expected result [2, 6] : I am comparing for every list in a and x , item 1 in a to item 1 in x , item 2 in a to item 2 in x .

So: a1_1 (9) (ie item 1 in list 1 of a ) is lower than x1_1 (10). a1_2 (10) is equal to x1_2 (10) - so that means there are 2 violations of the condition. a3_1 (11) > x1_1 (10) and a3_2 (12) > x1_2 (11) and the other lists in a are also higher than their corresponding elements. For x2 (2nd list in x):, all lists in a are lower except a7, in which a7_1 (15) is higher than x2_1 and a7_2 is higher than x2_2. Hence [2, 6] .

I can't quite follow your reasoning in your code, but you can check a against x in a single list comprehension:

x = [[10], [14]]
a = [[9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16]]

def touch(x, a):
    return [[ all([asel > xel[0] for asel in ael]) for ael in a].count(False) for xel in x]
touching = touch(x, a)
print(touching)

>>> [2,6]

Depending on what you really need, you can change the > condition to >= or count either False or True values. If the inner lists of x contain multiple element instead of one given in the example, you need to loop the inner lists as well:

x = [[10, 11], [14, 12]]
a = [[9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16]]

def touch(x, a):
    return [[all([asel > xsubel for xsubel in xel for asel in ael]) for ael in a].count(False) for xel in x ]
touching = touch(x, a)
print(touching)

You can use Numpy to avoid any for loops. In the code below I assumed that the list x was 1-D by the way, since it seems the sublists it contains consist of 1 element.

import numpy as np
x = [10,14]
a = [[9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16]]

e = np.array(x)
f = np.array(a)
touching = (np.sum(np.any(f[...,np.newaxis] <= e, axis = 1), axis = 0))
 
print(touching)

I have a different perspective. In python, you can see that:

>>> [1, 1] > [1, 2]
False
>>> [1, 1] > [1, 1]
False
>>> [1, 1] > [1, 0]
True
>>> [2, 3] > [3, 3]
False
>>> [2, 3] < [3, 3]
True
>>> [2, 2] > [0, 2]
True

So, we can compare entire lists. First flatten the x and, then compare x with element in a

x = [[10], [14]]
a = [[9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16]]

def touch(e, f):
    e = [q for p in e for q in p] # [10, 14]
    return sum([1 for sub_list in f if sub_list > e])

print(touch(x, a))

Here is a simple solution without any need for numpy

x = [[10], [14]]
a = [[9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16]]

def touch(e, f):
    # We can keep only maximum element of each list
    e = [max(lst) for lst in e]
    count = [0]*len(e)
    for lst in f:
        # Even the minimum must be greater
        min_value = min(lst)
        for i in range(len(e)):
            if min_value>e[i]:
                count[i] += 1
    return count

touching = touch(x, a)
print(touching)
# [5, 1]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM