Давайте распакуем это немного.
Нет встроенного способа сделать элемент-мудрый or
(логический или побитовый) на двух кортежах. Ответ Моргана Трэппа показывает хороший способ написать свой собственный, поэтому, если вы хотите поддерживать текущее состояние в цикле for, это так, как я бы пошел. Выражение генератора будет легко понято людьми, знакомыми с Python - хотя я бы использовал tuple(a or b for a, b in zip(result, new_result))
, а не a | b
, если я действительно не хочу побитовой версии.
В массивах Numpy есть функция logical_or
, которая работает по-элементной, но это было бы серьезным излишеством, если бы у вас было только небольшое количество кортежей с булевыми элементами.
Альтернативой сохранению запущенного состояния является сбор всех исходных кортежей и вычисление окончательного булева кортежа значений из списка кортежей результатов. Это было бы неприемлемо, если вы собираетесь закончить цикл раньше (скажем, если все элементы вашего накопленного кортежа результата равны True), или если ваш цикл имеет достаточно итераций, которые важны для использования памяти. Однако, в зависимости от ваших вкусов, это может быть яснее. Это, по сути, то же самое решение, что и выполнение общего числа числовых значений по сравнению с просто собиранием значений по мере того, как цикл запускается и суммируется впоследствии, и будет моим предпочтительным подходом, если для экземпляров вы переработаете цикл for как итератор кортежей результатов.
Это будет выглядеть примерно так:
result_list = []
for j in some_list:
result_list.append(method(j))
result = tuple(any(grouped) for grouped in zip(*result_list))
zip
на звезды вспененного результата списка будет группы всего первого/второго/третье значения в списке кортежей как п длиной кортежи, где n означает число от результатов, и any
эффективно or
s их вместе.EG:
>>> result_list = [(False, True, False), (True, False, False), (False, False, False), (True, True, False)]
>>> zip(*result_list)
[(False, True, False, True), (True, False, False, True), (False, False, False, False)]
>>> tuple(any(grouped) for grouped in zip(*result_list))
(True, True, False)
С or
над булевыми эквивалентно добавлением над числами, и any
эквивалентно sum
, вы можете рассмотреть аналогичные модели с Интс. цикл/версия множественного присваивания:
sums = (0, 0, 0)
for j in some_list:
result = method(j)
sums[0] += result[0]
sums[1] += result[1]
sums[2] += result[2]
против экспрессии генератора работающей версии Сумма:
sums = (0, 0, 0)
for j in some_list:
result = method(j)
sums = (a + b for a, b in zip(sums, result))
против накопления и суммирования списка результатов:
result_list = []
for j in some_list:
result_list.append(method(j))
sums = tuple(sum(grouped) for grouped in zip(*result_list))
Этот вариант является особенно хорошо, если ваш цикл for
не имеет никакого другого тела, так как вы можете свернуть все это на любой уровень выражений генератора/списка, который вам нравится:
result_list = [method(j) for j in some_list]
sums = tuple(sum(grouped) for grouped in zip(*result_list))
или:
sums = tuple(sum(grouped) for grouped in zip(*(method(j) for j in some_list)))
У вас есть особая причина, чтобы быть с помощью побитового оператора на 'bool's? –
@Josh: Это то, что использовалось в коде - нужно ли его изменить или? –
Я бы так подумал. См. [Логические операторы Python vs побитовые операторы] (http://stackoverflow.com/q/3845018), если вам нужна дополнительная информация. –