Python: Почему для понимания двухмерного списка требуется внешний цикл перед внутренним циклом?

Использование password_hash - рекомендуемый способ хранения паролей. Не разделяйте их на БД и файлы.

Допустим, у нас есть следующий ввод:

$password = $_POST['password'];

Я не проверяю ввод только ради понимания концепции .

Сначала вы вводите пароль:

$hashed_password = password_hash($password, PASSWORD_DEFAULT);

Затем см. вывод:

var_dump($hashed_password);

Как вы видите, это хешировано. (Я предполагаю, что вы сделали эти шаги).

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

// Query the database for username and password
// ...

if(password_verify($password, $hashed_password)) {
    // If the password inputs matched the hashed password in the database
    // Do something, you know... log them in.
} 

// Else, Redirect them back to the login page.

Официальная ссылка

2
задан Leo Jiang 3 March 2019 в 01:05
поделиться

4 ответа

Циклы for должны быть такими же, как если бы вы записали их «нормальным» способом:

for row in table:
    for cell in row:
        print(cell)

Поэтому, когда вы включаете это в понимание списка, вы оставляете циклы как есть ( за исключением удаления ":") и просто вытянуть окончательное выражение в начало:

# you can actually "abuse" list comprehensions to have short
# loops like this, even if you don't care about the list being
# generated. It's generally not a great practice though
[print(cell) for row in table for cell in row]

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

[for row in table for cell in row cell]

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

0
ответ дан Nathan 3 March 2019 в 01:05
поделиться

Как парсер видит это?

Синтаксические правила для таких выражений в python называются «дисплеями». Вы можете найти определение здесь .

comprehension ::=  expression comp_for
comp_for      ::=  ["async"] "for" target_list "in" or_test [comp_iter]
comp_iter     ::=  comp_for | comp_if
comp_if       ::=  "if" expression_nocond [comp_iter]

элементы нового контейнера - это те элементы, которые будут получены при рассмотрении каждого из предложений for или if в блоке, вложенности слева направо и оценке выражения для производить элемент каждый раз, когда достигается самый внутренний блок.

Повторяемое выражение в крайнем левом предложении for вычисляется непосредственно во включающей области, а затем передается в качестве аргумента для имплицитно вложенной области. Последующие для предложений и любое условие фильтра в крайнем левом для предложения не могут быть оценены во включающей области видимости, поскольку они могут зависеть от значений, полученных из крайнего левого итерируемого.

Возьмем ваш пример:

[cell for row in table for cell in row]

Интерпретатор разобьет его следующим образом:

expression = "cell"
comp_for1  = "for row in table" + comp_for2
comp_for2  = "for cell in row"

Затем интерпретатор восстановит вложенный цикл в иерархии

. ]
comp_for1:
    comp_for2:
        expression
0
ответ дан Gusi Gao 3 March 2019 в 01:05
поделиться

Я согласен, что ваша первая попытка в целом более интуитивна, так как она более близко имитирует то, как я и, вероятно, большинство людей думаем о переборе вещей от более специфического к менее конкретному.

Понятие вложенного списка Python адаптировано из вложенного цикла for:

for row in table:
    for cell in row:
        cell

Объединить строки:

for row in table: for cell in row: cell

Обернуть его в скобки списка, удалить : и переместите повторяющееся выражение вперед:

[cell for row in table for cell in row]
0
ответ дан Peter Leimbigler 3 March 2019 в 01:05
поделиться

Вы можете подумать, что понимание - это внутренняя версия цикла for. По крайней мере, я сделал сначала. Но самый простой способ понять это - заметить, что вы вызовете переменную до ее определения в первой попытке. row вызывается до его определения. Логично, что вы получите ошибку.

[cell for cell in row ...]

row не определено

[cell for row in table for cell in row]

Здесь нет проблем

0
ответ дан busybear 3 March 2019 в 01:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: