2014-04-15 2 views
0
remove = ['files/2013/','files/2014/'] 
list = ['/5/files/2013', '/20/files/2014', '/31/files/2009', '/6/files/2008'] 

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

finallist = ['/31/files/2009', '/6/files/2008'] 

Я попытался следующий код, но не смог получить его. Может ли кто-нибудь рассказать, как и объяснить самый простой способ сделать это?

remove = ['files/2013/','files/2014/'] 
list = ['/5/files/2013', '/20/files/2014', '/31/files/2009', '/6/files/2008'] 
finallist = [] 
for a in list: 
     for b in remove: 
      if not b in a: 
       finallist.append(a) 
+1

использовать функцию 'any' –

+0

Не использовать' list' в качестве имени переменной, она маскирует встроенный тип. –

+0

@NiklasB .: собственно, 'str.endswith()' здесь лучше. –

ответ

2

Используйте список понимание только держать значения. Сделайте remove кортеж, так что вы можете использовать str.endswith():

remove = tuple('/' + r.rstrip('/') for r in remove) 
finallist = [f for f in files if not f.endswith(remove)] 

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

Демо:

>>> remove = ('/files/2013','/files/2014') 
>>> files = ['/5/files/2013', '/20/files/2014', '/31/files/2009', '/6/files/2008'] 
>>> [f for f in files if not f.endswith(remove)] 
['/31/files/2009', '/6/files/2008'] 

Если вам необходимо проверить для сдерживания, а не окончание, вы должны будете использовать any() для эффективного согласования:

[f for f in files if not any(r in f for r in remove)] 

который проверяет каждую строку в remove в свою очередь, посмотреть, содержится ли он в имени файла; если так any() returns Истина, как только один такой тест пройдет успешно.

+0

Есть ли эквивалент python строки string1.contains (s2) java? Потому что я не могу быть уверен, что строка всегда заканчивается на «файлы/ /», там могут быть файлы//<несколько более вложенных папок> ' – NEO

+0

[f для файлов f, если они не являются (r in f for r in remove)] Можете ли вы объяснить, как это работает? Я от фона Java, если это помогает. – NEO

+1

@Naren: '(r in f for r in remove)' является выражением-генератором; каждый раз, когда вы перебираете его (извлекаете следующее значение), запускается тест 'r in f'; поэтому для каждой строки в 'remove' мы проверяем, содержится ли она в имени файла. 'any()' выполняет итерацию; как только такой тест «True», 'any()' останавливает цикл и возвращает 'True'. В противном случае он вернет «False». Таким образом, это означает, что мы включаем только имена файлов, для которых нет 'r' в' remove', содержащихся в имени файла. –

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