#python
#python
Вопрос:
У меня есть скрипт, который перебирает 42 координаты X и Y в строке и находит координату X, соответствующую наибольшему значению Y в этой строке. Он возвращает 1 (True), если значение X соответствует наибольшему значению Y, иначе он возвращает 0.
Все работает нормально. Я просто немного смущен тем, почему это работает. Я опубликую соответствующий раздел кода из скрипта, а затем обсудим ту часть, в которой я запутался впоследствии.
for row in reader:
vals = row[0:84]
vals = [float(v) for v in vals] # convert from strings to floats
max_i = np.nanargmax(vals[1::2]) # go from index 1 in steps of 2, ie. only the y values, and find the max y value. Ignore NA results.
fan_line = 0
for i in range(0,84,2): # go through x values
fan_line = 1
max_y = 1 if max_i*2 == i else 0 # note, it's max_i*2 because max_i is the index in just the y list (vals[1::2])
Строка, которая меня смущает, это:
max_y = 1 if max_i*2 == i else 0 # note, it's max_i*2 because max_i is the index in just the y list
Я знаю, что там есть объяснение после #, но, честно говоря, я этого не понимаю. Человек, который написал сценарий, однажды объяснил мне это, и это имело смысл, но они больше не являются частью моего отдела. Мне бы очень хотелось точно знать, что происходит, на случай, если это пригодится для будущих проектов. Я понимаю остальную часть кода, но эта одна строка сбивает меня с толку.
Редактировать
Извините, я должен был уточнить, что именно я не понял. Я не могу понять, что max_i*2 == i
делает. Как max_i*2
относится к «i»?
Ответ №1:
Это троичный оператор в Python:https://docs.python.org/3/reference/expressions.html#conditional-expressions
Строка
max_y = 1 if max_i*2 == i else 0
эквивалентно
if max_i*2 == i:
max_y = 1
else:
mas_y = 0
Комментарии:
1. Спасибо за ваш ответ. Теперь я понимаю, что мне было неясно, в чем заключалась моя проблема. Тем не менее, я нахожу вашу разбивку троичных операторов полезной.
Ответ №2:
В строке max_i = np.nanargmax(vals[1::2])
он создает массив с каждым вторым значением, затем находит позицию максимума в этом массиве «каждое второе значение».
Чтобы получить позицию в исходном массиве, нам нужно умножить ее на два (и добавить единицу).
Например:
>>> alphabet
'abcdefghijklmnopqrstuvwxyz'
>>> alphabet[1::2]
'bdfhjlnprtvxz'
>>> alphabet[1::2].index('j')
4
>>> alphabet[4*2 1]
'j'
>>>
Предложение по рефакторингу: чтобы сделать код менее запутанным, преобразуйте данные в список кортежей при первой возможности; либо с помощью more_itertools.chunked
, либо points = list(zip(vals[0::2], vals[1::2]))
Комментарии:
1. Спасибо за ваш ответ. Это очень понятно и имеет смысл. Ваш пример также был очень полезен.