我有一些数据存储在列表中,如果打印列表,我会看到以下内容:

.
.
.
007 A000000 Y
007 B000000  5
007 C010100  1
007 C020100 ACORN FUND
007 C030100 N
007 C010200  2
007 C020200 ACORN INTERNATIONAL
007 C030200 N
007 C010300  3
007 C020300 ACORN USA
007 C030300 N
007 C010400  4
.
.
.

序列之前和之后的点表示存在类似结构的其他数据,但可能是也可能不是第七项 (007) 的一部分。如果第七项中的第一个值是“007 A000000 Y”,那么我想创建一些数据项的字典列表。我可以做到这一点,并且已经通过运行列表中的所有项目并将它们的值与变量的一些测试值进行比较来做到这一点。例如一行代码:

if dataLine.find('007 B')==0:
    numberOfSeries=int(dataLine.split()[2])

我想做的是

if dataLine.find(''007 A000000 Y')==0:
    READ THE NEXT LINE RIGHT HERE

现在我必须遍历每个周期的整个列表

我想缩短处理时间,因为我有大约 60K 个文件,每个文件有 500 到 5,000 行。

我考虑过创建另一个对列表的引用并计算数据线,直到 dataLine.find(''007 A000000 Y')==0。但这似乎并不是最优雅的解决方案。

有帮助吗?

解决方案 5

好吧,当我在谷歌上搜索以确保我已经了解了我的基础时,我遇到了一个解决方案:

我发现即使我使用列表和字典,我也会忘记用它们来思考。Python 有一些强大的工具可以处理这些类型,以提高您操作它们的能力。
我需要一个切片,以便可以通过以下方式轻松获得切片引用

beginPosit = tempans.index('007 A000000 Y')
endPosit = min([i for i, item in enumerate(tempans) if '008 ' in item])

tempans是数据师,现在我可以写

for line in tempans[beginPosit:endPosit]:
    process each line

我想我回答了我自己的问题。我从其他答案中学到了很多并且很欣赏它们,但我认为这就是我需要的

好的,我将进一步编辑我的答案。我在这里学到了很多东西,但其中一些东西仍然超出了我的能力范围,我想在更多地了解这个神奇工具的同时编写一些代码。

from itertools import takewhile
beginPosit = tempans.index('007 A000000 Y')
new=takewhile(lambda x: '007 ' in x, tempans[beginPosit:])

这是基于之前对类似问题的回答,并且 史蒂文·休维格 回答

其他提示

可以使用itertools.groupby()区隔序列分成多个子序列。

import itertools

for key, subseq in itertools.groupby(tempans, lambda s: s.partition(' ')[0]):
    if key == '007':
    for dataLine in subseq:
        if dataLine.startswith('007 B'):
        numberOfSeries = int(dataLine.split()[2])

itertools.dropwhile()也将工作,如果你真的只是想寻求到那个行,

list(itertools.dropwhile(lambda s: s != '007 A000000 Y', tempans))
['007 A000000 Y',
 '007 B000000  5',
 '007 C010100  1',
 '007 C020100 ACORN FUND',
 '007 C030100 N',
 '007 C010200  2',
 '007 C020200 ACORN INTERNATIONAL',
 '007 C030200 N',
 '007 C010300  3',
 '007 C020300 ACORN USA',
 '007 C030300 N',
 '007 C010400  4',
 '.',
 '.',
 '.',
 '']

您可以将数据读入的字典。假设你从类文件对象infile读:

from collections import defaultdict
data = defaultdict(list)
for line in infile:
    elements = line.strip().split()
    data[elements[0]].append(tuple(elements[1:]))

现在,如果你想读“007 A000000 Y”线之后,你可以这样做的:

# find the index of ('A000000', 'Y')
idx = data['007'].index(('A000000', 'Y'))
# get the next line
print data['007'][idx+1]

使用字典中的所有数据的唯一困难是,一个真正的大的字典可能成为麻烦。 (这是我们习惯称之为“大奥莱矩阵”的方式。)

一个解决方案是构建在字典的索引,建立密钥 - 的映射>偏移,使用tell方法得到的文件偏移值。然后,你可以通过与seek方法寻求参考线一次。

你说你想做到这一点:

if dataLine.find(''007 A000000 Y')==0:
    READ THE NEXT LINE RIGHT HERE

据推测,这是一个“数据线在数据”环路内。

另外,也可以在一个使用迭代器,而不是直接的for循环:

>>> i = iter(data)
>>> while i.next() != '007 A000000 Y': pass  # find your starting line
>>> i.next()  # read the next line
'007 B000000  5'

您还别说有60K的文件进行处理。他们全部类似格式化?他们需要以不同的方式处理?如果他们都可以处理同样的方式,你可以考虑在一个单一的流链接在一起,其中:

def gfind( directory, pattern="*" ):
    for name in fnmatch.filter( os.listdir( directory ), pattern ):
        yield os.path.join( directory, name )

def gopen( names ):
    for name in names:
        yield open(name, 'rb')

def gcat( files ):
    for file in files:
        for line in file:
            yield line

data = gcat( gopen( gfind( 'C:\datafiles', '*.dat' ) ) )

这可以让你懒惰地处理在一个迭代器的所有文件。不知道是否可以帮助你目前的情况,但我认为这值得一提的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top