Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #81690

Re: Iterate over text file, discarding some lines via context manager

Path csiph.com!usenet.pasdenom.info!news.etla.org!news.stack.nl!newsfeed.xs4all.nl!newsfeed3.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail
Return-Path <python-python-list@m.gmane.org>
X-Original-To python-list@python.org
Delivered-To python-list@mail.python.org
X-Spam-Status OK 0.000
X-Spam-Evidence '*H*': 1.00; '*S*': 0.00; 'pycon': 0.01; 'subject:text': 0.05; 'context': 0.07; 'discard': 0.07; 'subject:file': 0.07; 'test,': 0.07; 'verbatim': 0.07; "'#'": 0.09; 'caller': 0.09; 'filter,': 0.09; 'line:': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'python': 0.11; 'def': 0.12; 'at,': 0.16; 'btw:': 0.16; 'empty,': 0.16; 'generator.': 0.16; 'iteration,': 0.16; 'line.split()': 0.16; 'paradigm.': 0.16; 'received:80.91.229.3': 0.16; 'received:plane.gmane.org': 0.16; 'ignore': 0.16; 'wrote:': 0.18; 'all,': 0.19; 'basically': 0.19; 'slightly': 0.19; 'example': 0.22; '(in': 0.22; 'header:User-Agent:1': 0.23; 'received:comcast.net': 0.24; 'space.': 0.24; 'sort': 0.25; "i've": 0.25; 'this:': 0.26; 'header:X-Complaints-To:1': 0.27; 'header:In-Reply-To:1': 0.27; 'leave': 0.29; 'am,': 0.29; "doesn't": 0.30; "i'm": 0.30; 'code': 0.31; 'getting': 0.31; 'easier': 0.31; 'lines': 0.31; 'subject:some': 0.31; 'open': 0.33; 'becomes': 0.33; "i'd": 0.34; 'etc': 0.35; 'but': 0.35; 'sequence': 0.36; 'yield': 0.36; 'should': 0.36; 'wrong': 0.37; 'operating': 0.37; 'starting': 0.37; 'skip:o 20': 0.38; 'manager': 0.38; 'to:addr:python-list': 0.38; 'sure': 0.39; 'to:addr:python.org': 0.39; 'received:org': 0.40; 'how': 0.40; 'dave': 0.60; 'is.': 0.60; 'solve': 0.60; 'simply': 0.61; "you're": 0.61; 'more': 0.64; 'feeling': 0.68; 'clearer': 0.84; 'subject:over': 0.84; 'subject:via': 0.84; 'angel': 0.91
X-Injected-Via-Gmane http://gmane.org/
To python-list@python.org
From Ned Batchelder <ned@nedbatchelder.com>
Subject Re: Iterate over text file, discarding some lines via context manager
Date Fri, 28 Nov 2014 11:01:03 -0500
References <CADjSo4Ro3xFj9T9gj0NO7YESE6G873vvrBD=Y=OAk-jNBRD5Bw@mail.gmail.com> <5478932A.1030509@davea.name>
Mime-Version 1.0
Content-Type text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding 7bit
X-Gmane-NNTP-Posting-Host c-50-133-228-126.hsd1.ma.comcast.net
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Thunderbird/24.6.0
In-Reply-To <5478932A.1030509@davea.name>
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.15
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <https://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list/>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <https://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
Newsgroups comp.lang.python
Message-ID <mailman.16410.1417190473.18130.python-list@python.org> (permalink)
Lines 75
NNTP-Posting-Host 2001:888:2000:d::a6
X-Trace 1417190473 news.xs4all.nl 2969 [2001:888:2000:d::a6]:57475
X-Complaints-To abuse@xs4all.nl
Xref csiph.com comp.lang.python:81690

Show key headers only | View raw


On 11/28/14 10:22 AM, Dave Angel wrote:
> On 11/28/2014 10:04 AM, fetchinson . wrote:
>> Hi all,
>>
>> I have a feeling that I should solve this by a context manager but
>> since I've never used them I'm not sure what the optimal (in the
>> python sense) solution is. So basically what I do all the time is
>> this:
>>
>> for line in open( 'myfile' ):
>>      if not line:
>>          # discard empty lines
>>          continue
>>      if line.startswith( '#' ):
>>          # discard lines starting with #
>>          continue
>>      items = line.split( )
>>      if not items:
>>          # discard lines with only spaces, tabs, etc
>>          continue
>>
>>      process( items )
>>
>> You see I'd like to ignore lines which are empty, start with a #, or
>> are only white space. How would I write a context manager so that the
>> above simply becomes
>>
>> with some_tricky_stuff( 'myfile' ) as items:
>>      process( items )
>>
>
> I see what you're getting at, but a context manager is the wrong
> paradigm.  What you want is a generator.   (untested)
>
> def mygenerator(filename):
>      with open(filename) as f:
>          for line in f:
>              if not line: continue
>              if line.startswith('#'): continue
>              items = line.split()
>              if not items: continue
>              yield items
>
> Now your caller simply does:
>
> for items in mygenerator(filename):
>        process(items)
>
>

I think it's slightly better to leave the open outside the generator:

def interesting_lines(f):
     for line in f:
         line = line.strip()
         if line.startswith('#'):
             continue
         if not line:
             continue
         yield line

with open("my_config.ini") as f:
     for line in interesting_lines(f):
         do_something(line)

This makes interesting_lines a pure filter, and doesn't care what sort 
of sequence of strings it's operating on.  This makes it easier to test, 
and more flexible.  The caller's code is also clearer in my opinion.

BTW: this example is taken verbatim from my PyCon presentation on 
iteration, it you are interested: http://nedbatchelder.com/text/iter.html

-- 
Ned Batchelder, http://nedbatchelder.com

Back to comp.lang.python | Previous | Next | Find similar | Unroll thread


Thread

Re: Iterate over text file, discarding some lines via context manager Ned Batchelder <ned@nedbatchelder.com> - 2014-11-28 11:01 -0500

csiph-web