Path: csiph.com!usenet.pasdenom.info!aioe.org!news.stack.nl!newsfeed.xs4all.nl!newsfeed2.news.xs4all.nl!xs4all!news.tele.dk!news.tele.dk!small.news.tele.dk!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.012 X-Spam-Evidence: '*H*': 0.98; '*S*': 0.00; 'output': 0.05; 'line:': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'def': 0.12; 'wrote': 0.14; "'b',": 0.16; '(actually': 0.16; "(you're": 0.16; "['a',": 0.16; 'itertools': 0.16; 'lambda': 0.16; 'message- id:@post.gmane.org': 0.16; 'received:80.91.229.3': 0.16; 'received:mediaways.net': 0.16; 'received:plane.gmane.org': 0.16; 'received:pool.mediaways.net': 0.16; 'code,': 0.22; 'import': 0.22; 'header:User-Agent:1': 0.23; 'this:': 0.26; 'header:X -Complaints-To:1': 0.27; 'idea': 0.28; 'rest': 0.29; 'wondering': 0.29; 'skip:g 30': 0.30; 'skip:( 20': 0.30; "i'm": 0.30; '(which': 0.31; 'usually': 0.31; 'subject:skip:i 10': 0.31; 'writes:': 0.31; 'file': 0.32; 'skip:- 30': 0.32; 'skip:# 10': 0.33; 'skip:s 30': 0.35; 'but': 0.35; 'there': 0.35; 'yield': 0.36; 'list': 0.37; 'starting': 0.37; 'jason': 0.38; 'to:addr:python-list': 0.38; 'expect': 0.39; 'to:addr:python.org': 0.39; 'skip:p 20': 0.39; 'received:org': 0.40; 'skip:n 30': 0.60; 'hope': 0.61; 'new': 0.61; 'such': 0.63; 'more': 0.64; 'as:': 0.81; "'2',": 0.84; "'3',": 0.84; 'avoids': 0.84; 'faster.': 0.84; 'lists:': 0.91; 'wanting': 0.93 X-Injected-Via-Gmane: http://gmane.org/ To: python-list@python.org From: Wolfgang Maier Subject: Re: itertools.groupby Date: Sat, 20 Apr 2013 21:14:48 +0000 (UTC) References: Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Gmane-NNTP-Posting-Host: sea.gmane.org User-Agent: Loom/3.14 (http://gmane.org/) X-Loom-IP: 95.115.38.107 (Mozilla/5.0 (Windows NT 6.2; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0) X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 85 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1366492505 news.xs4all.nl 2207 [2001:888:2000:d::a6]:43660 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:43967 Jason Friedman gmail.com> writes: > > I have a file such as: > > $ cat my_data  > Starting a new group > > a > b > c > Starting a new group > 1 > 2 > 3 > > 4 > Starting a new group > X > Y > Z > Starting a new group > > > I am wanting a list of lists: > ['a', 'b', 'c'] > > ['1', '2', '3', '4'] > ['X', 'Y', 'Z'] > [] > > I wrote this: > > ------------------------------------ > #!/usr/bin/python3 > from itertools import groupby > > def get_lines_from_file(file_name): >     with open(file_name) as reader: >         for line in reader.readlines(): >             yield(line.strip()) > > counter = 0 > def key_func(x): >     if x.startswith("Starting a new group"): >         global counter >         counter += 1 >     return counter > > for key, group in groupby(get_lines_from_file("my_data"), key_func): >     print(list(group)[1:]) > ------------------------------------ > > > > > I get the output I desire, but I'm wondering if there is a solution without the global counter. > Here's a solution that makes use of groupby (which is a good idea I think), but avoids the counter (actually this is trivial; you just return the result of startswith directly). It also provides you with the rest of the separator line (you're using startswith in your code, so I figured you expect more on these lines). I replaced the startswith() with slicing though as this is usually faster. def separate_on(iterable, separator): sep_len=len(separator) grouped_iter = (x[1] for x in groupby(iterable, lambda line: line[:sep_len] == separator)) for separator_line in grouped_iter: rest_of_separator_line = next(separator_line)[sep_len:].strip() yield (rest_of_separator_line, [s.strip() for s in next(grouped_iter)]) then for sep_tail, group in separate_on(your_input,your_separator): do_what_ever() Hope it's what you want, Wolfgang