Сравнение значений в списке в цикле For; питон

1

Работа в Python 2.7.

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

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

Я хотел бы иметь возможность сравнивать позиционные значения каждого списка ex- A [1] v B [1] - и суммировать экземпляры, в которых A больше (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, кодируя дополнительные, если инструкции для учета всех возможных вариантов. Очевидно, что это становится очень трудоемким по мере роста размера списка. Там должен быть более простой способ, не так ли?

Теги:
list
loops
if-statement
random

5 ответов

4
Лучший ответ

Похоже, вы хотите сделать 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
  • 0
    Отлично! Большое спасибо.
2

Чтобы добавить к другим ответам (и выполнить то же упрощение, что и попытка digivampire), вы можете использовать свободную функцию 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 -many раз, 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

Я думаю, что вы хотите сделать 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'
  • 0
    Спасибо за подсказку на молнии!
1

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

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

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

Кроме того, может быть лучше, более "python-y".

  • 0
    Неважно, мне больше нравится ответ Йохена Ритцеля! :)
  • 0
    Ах. Да, это имеет смысл. Благодарю.
0
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
  • 1
    Вычитание и последующее сравнение результатов с 0 является непифоническим в том смысле, что оно пропускает более простой подход cmp , и OP, очевидно, хочет накапливать выигрыши / связи / потери каждый раз в цикле, а не сбрасывать их.
  • 0
    Ах, ты абсолютно прав. Спасибо за указание на это.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню