2012-04-14 14 views
15

Mam 2 pętle i chcę, aby było lepiej jak zrozumienie list lub lambda lub inaczej. Jak mogę osiągnąć to samo?napisać lepszy kod zamiast 2 dla pętli

na przykład:

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

Najpierw polecam, aby naprawdę tego potrzebować. Na przykład przewodnik w stylu Pythona sugeruje, że Twój kod jest w porządku (tutaj jest część o [zrozumieniu list] (http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=List_Comprehensions#List_Comprehensions), funkcje lambda są poniżej). – Tony

Odpowiedz

27

Kod jest w porządku, jak to jest. Możesz uczynić ją mniej czytelną, wprowadzając niepotrzebne złożone konstrukcje.

+0

@thebjom: czy możesz wyjaśnić, które niepotrzebne skomplikowane konstrukcje? – sam

+2

Ani spisane wyrażenia, ani lambdy nie poprawią klarowności tego kodu, dlatego tylko dodają złożoności. Są oczywiście sytuacje, w których mogą wyjaśnić sprawę, ale nie jest to jeden z tych czasów. – thebjorn

+3

+1. I, Pythonic == Angielski. Czasami nie masz wyboru, ale pisanie przy użyciu 2, 3 lub nawet 4 zagnieżdżonych pętli, ponieważ trudno jest użyć zrozumienia lub lambda. A podsłuch ze stylem może zabrać cię na zawsze do debugowania i pisania dokumentacji. – CppLearner

4

Można skompresować dwie pętle for w pojedynczą pętlę generator expression *, z nową pętlą for, aby wyodrębnić z niej nazwy plików.

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

Jako druga odpowiedź powiedział, to nie lepiej, to gorzej i nie należy go używać (nie jestem pewien, że wystarczy nacisk!). O wiele trudniej jest zrozumieć, co się dzieje, i prawdopodobnie ma niewielką przewagę wydajności (w rzeczywistości dodatkowe warstwy pośrednie oznaczają, że prawdopodobnie będzie wolniej).

(* zasadzie równoważne listowego, ale lepiej w takich sytuacjach.)

2

Długie wyrażenie jest trudne do odczytania, gdy trzeba zeskanować do prawej i okrągłe plecy. jest jeszcze gorzej, gdy istnieje wiele zmiennych lokalnych, lambda i pojmowanie, po prostu oddzielone parens i przecinkami, w kilku linijkach. Używaj ich tylko wtedy, gdy Twój kod nie staje się dłuższy i bardziej złożony.
Dla ciebie, wolę wyodrębnić find jako kompromis. Ale tak jak powiedziała najwyższa odpowiedź, twój kod jest wystarczająco dobry.

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

Zrobiłbym to jak poniżej. Powodem jest to, że teraz możesz oddzielać tworzenie wzorca wyszukiwania, wyszukiwanie i przechowywanie plików. Łatwiej jest się rozwinąć, jeśli nie są ze sobą powiązane.

Jeśli twój system jest nieco egzotyczny (na przykład rozproszony dysk sieciowy), linia z globem i os.path.join jest nieprzyjemną linią. Chociaż, jak wspomnieli inni, dwie pętle są idealnie w porządku.

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 
Powiązane problemy