2012-04-14 3 views
15

У меня есть 2 для циклов, и я хочу сделать его лучше, как понимание списка или лямбда или другое. Как я могу достичь того же?напишите лучше код вместо 2 для циклов

, например:

filename = ['a.txt', 'b.txt', 'c.txt'] 
for files in filename: 
    for f in glob.glob(os.path.join(source_path, files)): 
     print f 
     ... some processing... 
+0

Я бы порекомендовал сначала, чтобы убедиться, что это действительно необходимо. Например, руководство по стилю Google Python показывает, что ваш код в порядке (см. Раздел [понимание списков] (http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=List_Comprehensions#List_Comprehensions), лямбда-функции ниже). – Tony

ответ

27

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

+0

@ thebjom: можете ли вы объяснить, какие ненужные сложные конструкции? – sam

+2

Ни понимание списка, ни лямбда не улучшат ясность этого кода, поэтому они только добавляют сложность. Есть, конечно, ситуации, когда они могут сделать вещи более ясными, но это не одно из тех времен. – thebjorn

+3

+1. И, Pythonic == Английский. Иногда у вас нет выбора, кроме как писать с использованием 2, 3 или даже 4 вложенных петель, потому что трудно использовать понимание или лямбду. И прослушивание со стилем может взять вас навсегда, чтобы отлаживать и писать документы. – CppLearner

4

Вы можете сжать две петли for в один generator expression *, с новым циклом for, чтобы извлечь из него имена файлов.

for f in (f_ for files in filename 
      for f_ in glob.glob(os.path.join(source_path, files))): 
    print f 
    # ... 

Как сказал другой ответ, это не лучше, это хуже и вы не должны использовать его (я не уверен, что это достаточно внимания!). Намного сложнее понять, что происходит, и, вероятно, имеет небольшое преимущество в производительности (на самом деле, дополнительные слои косвенности означают, что он, вероятно, будет медленнее).

(* в основном эквивалентен список понимание, но лучше в подобных ситуациях.)

2

Длинные выражения трудно читать, когда вы должны сканировать направо и круглую спину. это еще хуже, когда есть много локальных переменных, лямбдов и понятий, просто разделенных паранами и запятыми, в нескольких строках. Используйте их только в том случае, если ваш код не становится длиннее и сложнее.
Для случая, я предпочитаю извлечь find в качестве компромисса. Но, как сказал верхний ответ, ваш код достаточно хорош.

from itertools import chain 

find = lambda p: glob.glob(os.path.join(source_path, p)) 
for file in chain(map(find, filename)): 
    """ 
    =) I like one-level indentation here. 
    =(I don't know which file pattern is used currently, 
     unless I use longer expression... 
    """ 
4

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

Если ваша система немного экзотична (например, распределенный сетевой диск), линия с glob и os.path.join является неприятной строкой. Хотя, как отмечали другие, две петли в норме.

filename = ['a.txt', 'b.txt', 'c.txt'] 

searchPatterns = [os.path.join(source_path, files) for files in filename] 

searchResults = [glob.glob(pattern) for pattern in searchPatterns] 

fileListFlat = sum(searchResults,[]) 

for file in fileListFlat: 
    print file