簡體   English   中英

Python中的程序控制流

[英]Program Control-Flow in Python

我有一些數據存儲在列表中,如果我打印出列表,則會看到以下內容:

.
.
.
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

現在我必須遍歷每個周期的整個列表

我想縮短處理時間,因為我大約有6萬個文件,每個文件有500到5,000行。

我曾考慮過要創建對列表的另一個引用並計算數據線,直到dataLine.find(''007 A000000 Y')== 0。 但這似乎不是最優雅的解決方案。

您可以使用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]

使用字典中的所有數據的唯一困難是,一個很大的字典可能會變得很麻煩。 (這就是我們過去所說的“大奧萊矩陣”方法。)

一個解決方案是在Dictionary中構造一個索引 ,使用tell方法獲取文件偏移值,從而創建key-> offset的映射。 然后,您可以通過使用seek方法進行查找來再次引用該行。

好的,而我正在谷歌搜索以確保自己覆蓋了基礎知識時,我遇到了一個解決方案:

我發現即使我使用列表和字典,也忘記了思考。 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:])

這是基於先前對類似問題答案以及史蒂芬·休伊格(Steven Huwig)的答案

您說您想這樣做:

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 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM