тернарный оператор в понимании списка работает не так, как ожидалось

#python #list #operating-system #list-comprehension

Вопрос:

ПРАВКА: этот вопрос, оказывается, вообще не связан с пониманием списка. Проблема была вызвана тем, что не был передан полный путь, а только имя os.path.isfile() файла, что делает его всегда равным False.

Почему понимание if/else в начале этого списка работает не так, как ожидалось? В приведенном ниже заявлении приведен список со всеми 0 (в противном случае).

 [1 if os.path.isfile(file) else 0 for file in os.listdir(path)]
 

Ожидаемый результат будет равен 1, если файл является файлом, и 0, если файл является каталогом
Я протестировал 1 if os.path.isfile(file) else 0 независимо на другой линии, и она работает так, как ожидалось (есть смесь 1 и 0). Я не могу найти никаких синтаксических проблем с моим утверждением о понимании списка.

Что еще интереснее, так это то , что если я заменю условие чем-то другим, например 1 if file else 0 , поведение изменится. Теперь каждый элемент становится 1, хотя ожидается, что некоторые из них будут равны 0 (опять же, я проверил их независимо, используя одно и то же условное выражение).

Я пытался улучшить bool() свое состояние, но это ничего не дает. Я также попробовал str(файл), и тоже никакой разницы.

Комментарии:

1. Это не похоже на то, что это имеет какое-либо отношение к пониманию списка. Вы передаете имена файлов вместо полных путей к файлам isfile .

2. file всегда будет оцениваться True в логическом контексте. В противном случае вам необходимо предоставить дополнительную информацию, чтобы сделать этот пример воспроизводимым.

3. @a_guest Wut? Это кажется очень неправильным…

4. @deceze Что ты имеешь в виду?

5. @a_guest Где file здесь оценивается как логическое значение?

Ответ №1:

Попробуйте передать абсолютный путь к файлу в isfile функцию:

 [1 if os.path.isfile(os.path.join(path, file)) else 0 for file in os.listdir(path)]

 

Вы также можете достичь этого без if :

 [int(os.path.isfile(os.path.join(path, file))) for file in os.listdir(path)]
 

Комментарии:

1. Вау, так вот в чем была проблема…спасибо, что указали на это, теперь это работает.

2. Рад помочь 🙂

Ответ №2:

Вы можете сделать это без троичного оператора:

 [int(os.path.isfile(os.path.join(path, file))) for file in os.listdir(path)]
 

или в зависимости от того, что вы планируете делать с полученным списком:

 [os.path.isfile(os.path.join(path, file)) for file in os.listdir(path)]
 

Я бы всегда предпочел более позднее