Python:项目项目直到项目中的stopterm?

时间:2008-12-03 14:11:57

标签: python

免责声明:我对python很新!

如果我想要一个文件的所有行,直到(编辑并包含)包含某些字符串stopterm的行,是否有一种方法可以使用它的列表语法?我希望有类似的东西:

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

现在,我已经

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

这不是世界末日,但由于Python语法的其余部分非常简单,我希望有一个思想 - > 1的Python行映射。

6 个答案:

答案 0 :(得分:10)

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)

这是一种保持停止线的方法:

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

答案 1 :(得分:5)

“我希望有1个思想 - > 1个Python行映射。”难道我们都不会喜欢以某种方式反映我们自然语言的编程语言吗?

你可以做到这一点,你只需要定义一次你独特的想法。然后你有你希望的1:1映射。

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

几乎就是这样。

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

有更多一般方法。 lassevkenum_while的{​​{1}}答案是这种简单设计模式的概括。

答案 2 :(得分:2)

那个itertools解决方案很整洁。我之前对一个方便的工具itertools.groupby感到惊讶。

但是,如果没有itertools我能做到这一点,我只是在修补。所以这就是 (虽然有一个假设和一个缺点:文件不是很大,它分别在线上进行一次额外的完整迭代。)

我创建了一个名为“try”的示例文件:

hello
world
happy
day
bye

一旦你读到文件并在变量名称行中包含行:

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

然后

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

给出了结果:

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

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

给出了结果:

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

所以你得到了最后一行 - 也包括停止期限行。

答案 3 :(得分:1)

忘了这个

留下答案,但将其标记为社区。有关正确的方法,请参阅Stewen Huwig的答案。


嗯,[x for en in enumerable]将运行,直到enumerable不再生成数据,if-part将允许你沿途过滤。

你可以做的是添加一个功能,并通过它过滤你的可枚举:

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;

当然,它看起来并不像你想要的那么好......

答案 4 :(得分:1)

我认为保持这种方式很好。复杂的单行并不是真正的pythonic,因为Guido不得不在某个地方设置限制,我想这就是它......

答案 5 :(得分:0)

我会使用Steven Huwig'sS.Lott's解决方案进行实际使用,但作为一个稍微狡猾的解决方案,这是获取此行为的一种方法:

def stop(): raise StopIteration()

usefullines = list(stop() if stopterm in line else line for line in file)

有点滥用这样一个事实:任何引发StopIteration的东西都会中止当前的迭代(这里是生成器表达式),并且比你想要的语法更难以阅读,但是会有效。