Сравнение значений в списке в цикле For;питон - PullRequest
1 голос
/ 03 ноября 2011

Работа в Python 2.7.

У меня есть два разных списка, A и B (упрощенный, чтобы пояснения были более понятными).

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

Я хотел бы иметь возможность сравнитьпозиционные значения каждого списка, за исключением A [1] v B [1] - и суммируют случаи, когда A больше (A «выигрывает»), случаи, когда два значения одинаковы (A «связывает»),и случаи, когда B больше (A "убытки").

Чтобы сделать вещи немного сложнее, я также использую random.shuffle (), чтобы каждый раз рандомизировать порядок списка через цикл for.

Сначала я попытался использовать:

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

А затем в каждом из операторов if кодировать дополнительные операторы if для учета всех возможных вариантов.Очевидно, что это становится очень трудоемким, поскольку размер списка растет.Должен быть более легкий путь, верно?

Ответы [ 5 ]

4 голосов
/ 03 ноября 2011

Звучит так, как вы хотите 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
2 голосов
/ 03 ноября 2011

Чтобы добавить к другим ответам (и выполнить то же упрощение, которое предпринял дигивампир), вы можете использовать бесплатную функцию cmp, чтобы упростить логику сравнения.Возвращает -1, 0 или 1 в зависимости от того, какое из двух значений больше.Затем мы можем count количество появлений каждого значения.

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)

Чтобы продолжить этот подход, мы можем позволить Python выполнить логику и суммирование внешнего цикла для нас.Идея состоит в том, чтобы построить списки длины-3 с результатами подсчета (используя понимание списка для итерации в диапазоне -1..1), а затем использовать другое понимание списка, чтобы получить эти результаты whatever -много раз, zipих снова (для составления трех списков подсчетов выигрышей, ничьих и проигрышей) и sum каждого из этих списков.

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)
    ))
)
2 голосов
/ 03 ноября 2011

Я думаю, что вы хотите zip, также не уверен, почему вы тасуете внутри цикла (опять же, я не совсем уверен, что вы здесь делаете). Я бы переместил это наружу, поскольку вы все еще получаете случайный эффект.

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

Одна заметка о zip, она выдаст вам список предметов, если вы получите самый короткий список. Пример:

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

выведет:

[(1, 'a'), (2, 'b')]   # Note the missing 'c'
1 голос
/ 03 ноября 2011

Не думаю, что это плохое начало. Я бы добавил внутренний цикл for, чтобы помочь с жестким кодированием:

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

В этом примере кода предполагается, что длина listA равна длине listB. Если это не так, вы можете выполнить некоторые дополнительные проверки.

Кроме того, может быть лучший, более "питон-у" способ.

0 голосов
/ 03 ноября 2011
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
...