2017-01-17 2 views
2

Попытка выяснить, как работает это параллельное назначение. Полный код может быть найден here. (Файл Ryth Github python). Вот что у меня проблемы с:Параллельное назначение Python

def assign_move(square): 

    # Parallel Assignment 
    target, direction = max(
     ((neighbor, direction) for direction, neighbor in enumerate(game_map.neighbors(square)) 
           if neighbor.owner != myID), 
           default = (None, None), 
           key = lambda t: t[0].production) 

я сломаю его вниз, насколько я знаю, но я, вероятно, делать что-то неправильно.

target, direction = max(iterable, default, key) 

Назначаем ли мы цель и направление к тому же? Я думал, что параллельное назначение было что-то вроде x, y = 5, 6

Теперь, если мы посмотрим на iterable, это следующее:

iterable = ((neighbor, direction) for direction, neighbor in enumerate(game_map.neighbors(square)) if neighbor.owner != myID) 

Как мы можем иметь (neighbor , direction) перед для цикла? Что здесь делает инструкция if? Не нужно ли что-нибудь ниже блока if для запуска, если neighbor.owner != myID?

Если итератор пуст, мы вернем None, None, как показано ниже?

default = (None, None), 

И это функция, которую мы используем для определения максимальной?

key = lambda t: t[0].production) 

фона, если это необходимо: Это код бот будет играть в игру Halite. Это готовый бот, найденный в этом GitHub repo.

+1

Это не цикл 'for' с выражением' if'; это [понимание списка с фильтром] (https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions) – Hamms

+0

Ahh perfect! Я понятия не имел, что даже искать для этой части. – Loaf

+2

@ Хаммс: Genex, а не LC. Нет квадратных скобок. –

ответ

1

max функция здесь возвращает максимальное tuple в (direction , neighbors) относительно neighbor.production (как мы понимаем это из key) и соседи могут участвовать в этой итерации, если neighbor.owner != myID происходит, и если итератор был пуст default = (None, None) будет target и directions , поэтому target - это neighbor с наибольшим количеством production в конце.

+0

если это было 't [1] .production' было бы' direction.production'? – Loaf

+1

Да, предположим, что 't' здесь ваш' tuple', поэтому первый элемент - 'сосед', а второй -' direction', и он не вернет ошибку, если класс 'direction' имел член' production'. – Arman

+1

Отлично! Спасибо за объяснение. Это значительно улучшает понимание и понимает, что 'for' и' if' isnt 'цикл for или оператор if/else. – Loaf

1

Всякий раз, когда в левой части задания есть несколько переменных, правая часть должна быть последовательностью с таким количеством элементов, которые распаковываются в отдельные переменные.

Иногда правая сторона явно строит эту последовательность: например, x, y = 5, 6 - это технически конструкция кортежа (5, 6), а затем его распаковка. (На самом деле, поскольку Python 2.6 здесь устраняется конструкция кортежа, но это внутренняя оптимизация, которая никогда не должна быть релевантной для вас.)

Однако на правой стороне действует ЛЮБОЙ источник последовательности правильной длины. В вашем примере target, direction = max(...)max выбирает элемент из списка 2-элементных кортежей (neighbor, direction). «Самый большой» из них (как определено параметром =) возвращается и распаковывается в цель и направление.

+0

Спасибо! Я сначала не думал о 'max (...)' возвращении всего, кроме одного значения. – Loaf

Смежные вопросы