Сравнение всех элементов двух кортежей (со всеми функциями ())
Поэтому я знаю, что сравнения на кортежах работают лексикографически:
Кортежи и списки сравниваются лексикографически с помощью сравнения соответствующих элементов. Это означает, что для сравнения равных, каждый элемент должен сравнивать равные и две последовательности должны быть одного типа и иметь одинаковую длину. Если они не равны, то последовательности упорядочиваются так же, как и их первые отличающиеся элементы. Например, cmp ([1,2,x], [1,2,y]) возвращает то же самое, что СМР(Х,Y). Если соответствующего элемента не существует, то сначала упорядочивается более короткая последовательность (например, [1,2]
Итак, из этого:
>>> a = (100, 0)
>>> b = (50, 50)
>>> a > b
True
Но я хочу сравнить все элементы 2 кортежей по порядку, поэтому функционально я хочу что-то похожее (используя значения сверху):
>>> a > b
(True, False) #returned tuple containing each comparison
>>> all(a > b)
False
В качестве примера на практике, для чего-то вроде координат экрана, если вы хотите проверить, было ли что-то "внутри" экрана при (0,0), но сделали сравнение, как coord > (0,0), если бы координата x была больше 0, но координата y была меньше, она все равно возвращала бы true, что в данном случае не требуется.
Как своего рода дополнительный вопрос / обсуждение:
Я не уверен, почему сравнение 2 кортежей разных значений возвращается таким образом. Вам не дается никакого индекса, поэтому единственное, что вы получаете от сравнения кортежа (это не проверка равенства), - это то, что в какой-то момент в кортеже одно из сравнений бросит истинное или ложное значение, когда они будут не равный. Как ты можешь этим воспользоваться?
5 ответов:
Вы можете достичь этого с помощью понимания списка и встроенного zip:
>>> a = (100, 0) >>> b = (50, 50) >>> [(a > b) for a, b in zip(a,b)] [True, False]
Вы можете использовать all() или any() в возвращаемом списке.
Замените
a > b
наtuple(i > j for i, j in zip(a,b))
во втором примере кода.>>> a = (100, 0) >>> b = (50, 50) >>> tuple(i > j for i, j in zip(a,b)) (True, False) >>> all(i > j for i, j in zip(a,b)) False
Вы можете рассмотреть возможность использования следующего векторизованного подхода , который обычно более эффективен и синтаксически / семантически очень ясен:
>>> import numpy >>> >>> a = (100, 0) >>> b = (50, 50) >>> numpy.array(a) > b array([ True, False], dtype=bool) >>> >>> (numpy.array(a) > b).any() True >>> (numpy.array(a) > b).all() False
Numpy довольно производителен, и результирующие объекты выше также вставляют любые()/все() методы запроса, которые вы хотите. Если вы будете выполнять вектор-подобные операции (как предполагает ваш пример экранных координат), Вы можете рассмотреть возможность работы с 'a' и 'b' в виде массивов numpy, а не кортежей. Это приводит к тому, что наиболее эффективная реализация того, что вы ищете: нет необходимости в предварительном преобразовании, и циклы на основе Python заменяются эффективными циклами на основе numpy. Это стоит подчеркнуть, потому что существует два и потенциально три цикла: (1) цикл предварительной обработки во время преобразования (который можно исключить); (2) Цикл сравнения элементов по элементам; и (3) цикл запроса для ответа на вопрос any/all.
Обратите внимание, что я мог бы также создать массив numpy из 'b', но не сделал этого исключен один шаг преобразования и время предварительной обработки . Поскольку этот подход приводит к одному операнду быть и NumPy массив и кортеж, а последовательность расти, которые могут не привести к менее быстрому постатейного сравнения (который строгий и NumPy-К-и NumPy хорошо). Попробовать его. :)
Я чувствовал, что использование функций map и lambda отсутствовало в ответах
>>> a = (100, 0) >>> b = (50, 50) >>> all(map(lambda x,y: x > y, a, b) False
Чтобы получить описанное поведение, попробуйте:
[ai > bi for ai,bi in zip(a,b)]
Причина, по которой сравнения кортежей возвращаются таким образом, заключается в том, что вы можете написать что-то вроде:
if a >= (0.,0.): print "a has only positive values" else: print "a has at least one negative value"
Если Python вернет Кортеж, который вы описываете, то другого никогда не произойдет. Попробуйте
if (False,False): print "True!" # This is what is printed. else: print "False!"
Надеюсь, это поможет.