简体   繁体   中英

Comparing Values in List in For Loop; Python

Working in Python 2.7.

I have two different lists, A and B (simplified to make explanations more clear).

A = [1, 2, 4, 3, 5]
B = [2, 0, 3, 2, 1]

I would like to be able to compare the positional values of each list ex- A[1] v B[1]- and total up the instances in which A is larger (A "wins"), the instances when the two values are the same (A "ties"), and the instances when B is larger (A "losses").

To make things a little more complicated I'm also using random.shuffle() to randomize the order of the list every time through a for loop.

I first tried using:

def listComp(listA, listB):
    Awins = 0
    Aties = 0
    Alosses = 0
    for i in range(0, whatever):
        random.shuffle(listA)
        random.shuffle(listB)
        if A[0] > B[0]:
            Awins += 1
        elif A[0] == B[0]:
            Aties += 1
        elif A[0] < B[0}:
            Alosses += 1

And then in each of the if statements, coding additional if statements to account for all the possible variations. Obviously, this gets very labor-intensive as the size of the list grows. There's got to be an easier way, right?

Sounds like you want zip :

def compare(A,B):
    Awins = 0
    Aties = 0
    Alosses = 0
    for i in range(0, whatever):
        random.shuffle(listA)
        random.shuffle(listB)
        for a,b in zip(A,B):
            if a > b:
                Awins += 1
            elif a == b:
                Aties += 1
            else:
                Alosses += 1

I think you want zip , also not sure why you are shuffling inside the loop (then again, I'm not exactly sure what you are accomplishing here). I'd move it outside, as you still get the random effect.

def listComp(listA, listB):
    wins = 0
    ties = 0
    losses = 0

    shuffle(listA)
    shuffle(listB)

    for a, b in zip(listA, listB):
        if a < b:
            wins += 1
        elif a == b:
            ties += 1
        else:
            losses += 1

    return wins, ties, losses

One note about zip , it'll give you a list of items as long as the shortest list you've given. Example:

zip([1, 2], ['a', 'b', 'c'])

will output:

[(1, 'a'), (2, 'b')]   # Note the missing 'c'

To add to the other answers (and accomplish the same simplification that digivampire attempted), you can use the free function cmp to simplify the comparison logic. It returns -1, 0 or 1 depending on which of two values is larger. We can then count the number of appearances of each value.

for i in range(0, whatever):
    random.shuffle(listA)
    random.shuffle(listB)
    results = [cmp(a, b) for a, b in zip(listA, listB)]
    Awins += results.count(1)
    Aties += results.count(0)
    Alosses += results.count(-1)

To go further with this approach, we can let Python do the outer loop logic and summation for us. The idea is to build length-3 lists with the count results (using a list comprehension to iterate over the -1..1 range), and then use another list comprehension to get these results whatever -many times, zip them again (to make three lists of win-counts, tie-counts and loss-counts) and sum each of those lists.

def trial(listA, listB):
    random.shuffle(listA)
    random.shuffle(listB)
    results = [cmp(a, b) for a, b in zip(listA, listB)]
    return [results.count(i) for i in range(-1, 2)]


Awins, Aties, Alosses = (
    sum(counts)
    for counts in zip(*(
        trial(listA, listB) for i in range(0, whatever)
    ))
)

I don't think this a bad start. I would add an inner for loop to help with the hard-coding:

def listComp(listA, listB):
        Awins = 0
        Aties = 0
        Alosses = 0
        for i in range(0, whatever):
            random.shuffle(listA)
            random.shuffle(listB)
            for j in range(0, len(listA)):
                if A[j] > B[j]:
                    Awins += 1
                elif A[j] == B[j]:
                    Aties += 1
                elif A[j] < B[j]:
                    Alosses += 1

This code sample assumes that the length of listA is the same as the length of listB. If this isn't true, you may want to do some additional checks.

Also, there may be a better, more "python-y" way.

for i in range(0, whatever):
    random.shuffle(listA)
    random.shuffle(listB)
    diffList = map(lambda (x,y): x-y, zip(listA,listB))
    Awins_ties = sum((k > 0, k==0) for k in diffList)
    Awins = Awins_ties[0]
    Aties = Awins_ties[1]
    Alosses = len(diffList) - Awins - Aties

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