Как написать «Если тип файла НЕ txt или csv, сделайте X» внутри цикла for?

#python

#python

Вопрос:

У меня есть каталог, содержащий три типа файлов (текстовые, csv и подкаталоги). Я написал версию скрипта, который я хочу применить к текстовым файлам, и исправленную версию, которую я хочу применить к csv-файлам внутри цикла for . Впоследствии я хочу игнорировать подкаталоги вместе с любыми другими типами файлов, которые у меня могут быть.

Я знаю, что могу сделать что-то вроде следующего…

 for file in glob.glob('*'):
    if file.endswith ('.txt'):
        # run script1 here
    elif file.endswith ('.csv'):
        # run script2 here
    else:
        continue
  

Но поскольку сценарий довольно длинный, я хотел бы инвертировать оператор ‘else’ в качестве оператора ‘if not’ в начале сценария — хотя бы для улучшения удобочитаемости. Я знаю, что могу сделать это с одним из типов файлов (.txt в данном случае)…..

 for file in glob.glob('*'):
    if not file.endswith ('.txt'):
        continue
    else:
        # run script1 here
  

Но как я могу изменить сценарий так, чтобы я спрашивал: «Если файл не является txt или csv, сделайте X, если файл имеет формат txt, сделайте Y, а если файл имеет формат csv до Z». Я подозреваю, что это простое решение, но я не могу его решить. Вот предыдущая попытка, которую я предпринял, которая выдает ошибку…

 for file in glob.glob('*'):
    if not file.endswith ('.txt') or ('.csv'):
        continue
    elif file.endswith ('.txt'):
        # run script1 here
    else:
        # run script2 here
  

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

1. просто опустите else предложение в вашем первом примере?

2. if not file.endswith('.txt') or file.endswith('.csv')

3.Обратите внимание, file.endswith ('.txt') or ('.csv') всегда будет true . Python не английский, даже если он иногда приближается, интерпретатор видит это как (file.endswith('txt')) or ('csv') и 'csv' всегда верно, т.Е. bool('csv')

4. Новая версия не короче, и я лично не думаю, что она более удобочитаема. В итоге вы напишете все возможные расширения дважды, а не только один раз. Если вы хотите улучшить читаемость, вам следует вместо этого рассмотреть возможность использования «script1» и «script2» в функциях.

5. Учитывая, что вам все равно нужно выполнить проверку, я думаю, что ваш первый пример самый ясный. Ставьте continue первое, только если остальная часть кода одинакова, независимо от того, заканчивается ли имя файла на .txt или .csv , без необходимости повторной проверки.

Ответ №1:

Каждое логическое выражение вычисляется отдельно.

not file.endswith ('.txt') or ('.csv') оценено верно: не пустой кортеж считается истинным значением.

 for file in glob.glob('*'):
    if not file.endswith ('.txt') or not file.endswith ('.csv'):
        continue
    elif file.endswith ('.txt'):
        # run script1 here
    else:
        # run script2 here
  

Ответ №2:

or объединяет два выражения; это не часть одного логического выражения.

 if not (file.endswith('.txt') or file.endswith('.csv')):
  

Однако endswith сам может принимать кортеж строк:

 if not file.endswith(('.txt', '.csv')):
  

Ответ №3:

В вашем третьем фрагменте кода вам придется снова вызвать .endswith() fumction, например:

 for file in glob.glob('*'):
    if not file.endswith ('.txt') or file.endswith('.csv'):
        continue
    elif file.endswith ('.txt'):
        # run script1 here
    else:
        # run script2 here
  

Это должно сработать

Ответ №4:

Поскольку вы все равно просматриваете файлы, почему не только glob файлы, которые вам действительно нужны?

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

 from glob import glob

for file in glob("*.txt")   glob("*.csv"):
    if file.endswith(".txt"):
        print("run script 1")
    else:
        print("run script 2")
  

Или даже лучше, чем это (IMO):

 from glob import glob

for file in glob("*.txt"):
    print("run script 1")

for file in glob("*.csv"):
    print("run script 2")
  

Ответ №5:

Поскольку имя файла имеет либо ‘.txt’, либо ‘.csv’, я думаю, вы получите желаемый результат, используя только оператор if и вам не нужно else:continue предложение, потому что, если в имени файла нет ни одного из них, условие if завершится неудачей и ничего не произойдет.

 for file in glob.glob('*'):
    if file.endwith('.txt'):
        #do something
    if file.endwith('.csv'):
        #do something