Python: element for element before stopterm in element?

Disclaimer: I'm pretty new to python!

If I need all the lines of the file until (edit and include) the line containing the string stopterm , is there a way to use the list syntax? I was hoping there would be something like:

 usefullines = [line for line in file until stopterm in line] 

At the moment I have

 usefullines = [] for line in file: usefullines.append(line) if stopterm in line: break 

This is not the end of the world, but since the rest of the Python syntax is so simple, I was hoping to display 1 thinking> 1 Python.

+3
source share
6 answers
 from itertools import takewhile usefullines = takewhile(lambda x: not re.search(stopterm, x), lines) from itertools import takewhile usefullines = takewhile(lambda x: stopterm not in x, lines) 

Here is the path that supports the stopterm line:

 def useful_lines(lines, stopterm): for line in lines: if stopterm in line: yield line break yield line usefullines = useful_lines(lines, stopterm) # or... for line in useful_lines(lines, stopterm): # ... do stuff pass 
+10
source

"I was hoping to display 1 thought -> 1 in Python." Don't we like a programming language that somehow reflects our natural language?

You can achieve this, you just need to identify your unique thoughts once. Then you have the 1: 1 card you were hoping for.

 def usefulLines( aFile ): for line in aFile: yield line if line == stopterm: break 

Pretty much that.

 for line in usefulLines( aFile ): # process a line, knowing it occurs BEFORE stopterm. 

There are more general approaches. lassevk answers to enum_while and enum_until are generalizations of this simple design pattern.

+5
source

This itertools solution is neat. I was previously struck by itertools.groupby, one convenient tool.

But still, I was just messing around if I could do it without itertools. So, here (There is one assumption and one drawback: the file is not huge, and it goes one additional full iteration along the lines, respectively.)

I created a sample file called "try":

 hello world happy day bye 

after you read the file and enter the lines in the line with the variable names:

 lines=open('./try').readlines() 

then

  print [each for each in lines if lines.index(each)<=[lines.index(line) for line in lines if 'happy' in line][0]] 

gives the result:

 ['hello\n', 'world\n', 'happy\n'] 

and

 print [each for each in lines if lines.index(each)<=[lines.index(line) for line in lines if 'day' in line][0]] 

gives the result:

 ['hello\n', 'world\n', 'happy\n', 'day\n'] 

Thus, you have received the last line - the terminal stop line is also included.

+2
source

Forget about it

Leaving an answer, but noting his community. See Stewen Huwig for the correct way to do this.


Well, [x for x in an enumerated] will work until the enumerated one generates data anymore, the if part will just let you filter along the way.

What you can do is add a function and filter it through it:

 def enum_until(source, until_criteria): for k in source: if until_criteria(k): break; yield k; def enum_while(source, while_criteria): for k in source: if not while_criteria(k): break; yield k; l1 = [k for k in enum_until(xrange(1, 100000), lambda y: y == 100)]; l2 = [k for k in enum_while(xrange(1, 100000), lambda y: y < 100)]; print l1; print l2; 

Of course, this does not look as good as you would like ...

+1
source

I think that everything is in order. The complex single-line font is not really pythonic, and since Guido was supposed to interrupt somewhere, I think it's him ...

+1
source

I would go with Stephen Houwig or S.Lott solutions for real use, but as a little hacky solution, here is one way to get this behavior:

 def stop(): raise StopIteration() usefullines = list(stop() if stopterm in line else line for line in file) 

It slightly abuses the fact that everything that causes StopIteration will interrupt the current iteration (here the generator expression) and uglier than your desired syntax, but it will work.

0
source

All Articles