2011-03-17 4 views
1

안녕하세요, 파일에서 특정 줄을 읽는 코드가 있는데 목록 작성 또는 생성자 표현/함수로 더 빨리 실행되는지 알고 싶습니다. 그리고 코드가 더 빨리 실행되면 코드는 어떻게 보이게 될까요? 파이썬 배우기. 덕분에 당신의 도움을목록 이해를위한 루프

input = open('C:/.../list.txt', 'r') 
output = open('C:/.../output.txt', 'w') 

x=0 

for line in input: 
    x = x+1 
    if x > 2 and x < 5: 
     output.write(line) 

목록 파일은 새 파일에

1 
2 
3 
4 
5 

출력

3 
4 
+5

성능이 왜 중요한가요? 이해하기 쉽고 유지 보수가 가능한 코드를 작성하는 방법을 배우는 것이 더 좋지 않습니까? 문제가되는 경우 성능을 걱정하십시오. 가능하다면 –

+2

+10까지 @David. 또한 파일 I/O는 데이터가 메모리에서 어떻게 처리되는지에 관계없이 어쨌든 느립니다. – delnan

답변

6

목록 이해를위한 필요 없음입니다 있습니다.

output.write(''.join(itertools.islice(inputfile, 2, 4)) 
+1

유일한 잠재적 인 함정은 이것이 전체 데이터를 메모리에 유지한다는 것입니다. 따라서 'stop-start'가 큰 경우 ... – delnan

2

당신은 발전기을 함께하고 싶어 : 사용하고

output.writelines([line for (x, line) in enumerate(input) if 1 < x < 4]) 

이 당신을 가정 당신은 지능형리스트를 사용하려면

output.writelines(line for line in input if 2 < int(line) < 5) 
+0

저는 단시간에 대해서는 모르지만 한 마디로만 작동하므로 메모리를 적게 사용합니다 한 번에. – theheadofabroom

+0

@Jochen : 고마워, 고칠 수 있었다. – Narcolei

+3

이것은 OP 코드에 존재하지 않는 입력 파일의 내용에 대한 종속성을 만듭니다. – martineau

1

가 빠르지 만, 파일에서 실제로 읽은 값이 아니라 파일 위치의 실제 행 수입니다 (할당 된 x로 판단하면 true).

0

발전기 대 목록 이해력에 대해 구체적으로 질문했지만 일반적으로 문제에 접근하는 방법이 몇 가지 있습니다.

발전기 버전 :

input = open('input.txt', 'r') 
output = open('output.txt', 'w') 

def gen() : 
    for line in input : 
     yield "FOO " + line 

for l in gen() : 
    output.write(l) 

목록 이해 :

output.writelines("FOO " + line for line in input) 

반복자 스타일 :

class GenClass(object) : 
    def __init__(self, _in) : 
     self.input = _in 

    def __iter__(self): 
     return self 

    def next(self) : 
     line = self.input.readline() 
     if len(line) == 0 : 
      raise StopIteration 
     return "FOO " + line 

output.writelines(GenClass(input)) 

생각 :

  • 목록 이해가 메모리에 코드의 양을 (함수 oneline 있습니다)
  • 발전기,
  • 반복자 스타일의 코딩 관행에 더 유연 당신에게 아마도 가장 유연성을 제공 제한합니다
  • 목록 이해를 다해야 할 것입니다
  • 약간 더 높은 초기화 비용 (대상)
0

가장 빠른 방법은 테스트하는 것입니다.

이 코드에서는 라인 값이 아닌 라인 값에 관심이 있다고 가정합니다.

import timeit 

def test_comprehension(): 
    input = open('list.txt') 
    output = open('output.txt','w') 
    [output.write(x) for x in input if int(x) > 2 and int(x) < 5] 

def test_forloop(): 
    input = open('list.txt') 
    output = open('output.txt','w') 

    for x in input: 
     if int(x) > 2 and int(x) < 5: 
      output.write(x) 

if __name__=='__main__': 
    times = 10000 

    from timeit import Timer 
    t = Timer("test_comprehension()", "from __main__ import test_comprehension") 
    print "Comprehension: %s" % t.timeit(times) 

    t = Timer("test_forloop()", "from __main__ import test_forloop") 
    print "For Loop: %s" % t.timeit(times) 

이 나는 ​​단지 몇 기능, 지능형리스트와 함께 않는 한, 그리고 forloop로 수행하는 또 다른를 설정하고있다. timeit 모듈은 지정한 횟수만큼 코드의 작은 비트를 실행하고 시간을 계산하여 실행하는 데 걸리는 시간을 반환합니다.위의 코드를 실행하는 경우 그래서 당신의 라인을 따라 뭔가의 출력을 얻을 것이다 :

이해 : 0.957081079483 For 루프 : 0.956691980362

이 음울만큼,이 같은 어느 쪽이든에 관하여이다.

+0

아마 I/O 바인딩이기 때문에 ... – martineau

0
def copyLines(infname, outfname, lines): 
    lines = list(set(lines)) # remove duplicates 
    lines.sort(reverse=True) 
    with open(infname, 'r') as inf, open(outfname, 'w') as outf: 
     try: 
      i = 1 
      while lines: 
       seek = lines.pop() 
       while i<seek: 
        inf.next() 
        i += 1 
       outf.write(inf.next()) 
       i += 1 
     except StopIteration: # hit end of file 
      pass 

def main(): 
    copyLines('C:/.../list.txt', 'C:/.../output.txt', range(3,5)) 

if __name__=="__main__": 
    main() 

원하는 줄이 부족하면 즉시 종료됩니다.