2013-04-17 34 views
-5

您好我所有的代碼允許我從數據中提取一些特定的信息,我希望有人幫助我使用一段時間寫得更合適,所以我可以做到這一點對於許多行現在我只有兩個線(數據)我是初學者,所以如果有人能幫助解釋一下,這樣我可以學習,而不僅僅是複製和粘貼=)如何在Python中使用「While()」

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 


import re 

tableau = [] 

data = "00:02:12.935 mta   Messages  I Doc O:NVS:FAXG3/ R:NVS:SMTP.0/[email protected] mid:6499" 

result1 = {} 
i = re.findall(r"^.[^\ ]*", data) 
j = re.findall(r"\d+$", data) 
k = re.findall(r"O:[^\ ]*", data) 
r = re.findall(r"R:[^\ ]*", data) 

result1 = {'Heure':i,'MID':j,'Source':k,'Destination':r} 

data = "00:03:12.935 mta   Messages  I Doc O:NVS:FAXG3/ R:NVS:SMTP.0/[email protected] mid:6599" 

result2 = {} 
i = re.findall(r"^.[^\ ]*", data) 
j = re.findall(r"\d+$", data) 
k = re.findall(r"O:[^\ ]*", data) 
r = re.findall(r"R:[^\ ]*", data) 

result2 = {'Heure':i,'MID':j,'Source':k,'Destination':r} 

tableau.append(result1) 
tableau.append(result2) 

print tableau 
+3

' while'是一個Python關鍵字,沒有「While()'」函數。 (另外,你可能需要一個'for'循環,因爲你正在遍歷一組特定的數據。) – geoffspear

+0

我不認爲'while'是你想要的。據我所知,一般來說,你將有'數據'作爲字符串列表。在這種情況下,你會使用'for..in ..'循環 – sashkello

+0

澄清你的問題 - 目前還不清楚你想循環通過什麼。 – sashkello

回答

6

這實際上是做了for loop更好:

data1 = "00:02:12.935 mta   Messages  I Doc O:NVS:FAXG3/ R:NVS:SMTP.0/[email protected] mid:6499" 
data2 = "00:03:12.935 mta   Messages  I Doc O:NVS:FAXG3/ R:NVS:SMTP.0/[email protected] mid:6599" 
data_list = [ data1, data2 ] #store the data in a list so we can iterate over it 
tableau = [] #create a list to hold our output 
for data in data_list: #iterate over the list, getting 1 "data" at a time 
    #extract info we want 
    i = re.findall(r"^.[^\ ]*", data) 
    j = re.findall(r"\d+$", data) 
    k = re.findall(r"O:[^\ ]*", data) 
    r = re.findall(r"R:[^\ ]*", data) 

    #create dictionary and append it to tableau 
    tableau.append({'Heure':i,'MID':j,'Source':k,'Destination':r}) 

更高級的用戶可能會使用的功能在這裏WH ICH取字符串作爲輸入,並返回所需的數據字典:

def extract(data): 
    i = re.findall(r"^.[^\ ]*", data) 
    j = re.findall(r"\d+$", data) 
    k = re.findall(r"O:[^\ ]*", data) 
    r = re.findall(r"R:[^\ ]*", data) 
    return {'Heure':i,'MID':j,'Source':k,'Destination':r} 

現在你可以在list comprehension使用:

tableau = [extract(data) for data in data_list] 

從評論,它看起來像你得到的來自文件的數據行。這甚至更好(誰想輸入所有這些字符串?)。現在,我們可以縮短這:

with open('filename') as fin: 
    tableau = [extract(data) for data in fin] 

使用with引入了另一個Python結構 - (上下文管理器)。這有點複雜,但它是打開文件的首選方式。對於文件對象,它的功能等同於:

fin = open('filename') 
tableau = ... 
fin.close() 
+0

謝謝!!!!!!! –

+0

這是一個很好的方法來解決這個問題,但是 - 我會建議在我的答案中使用正則表達式,因爲它更快。 –

+0

是的,但我無法在Python 2.6中使用它:/ –

0

我不認爲雖然是最好的方式來做你所期望的。也許你可以使用

for data in dataArray: 

凡dataArray中包含的數據串。

3

這裏。這將以更有效的方法解析數據,它使用一個函數,您可以只提供一個數據列表。如果你想把它變成一個發電機,它也很容易。

import re 

def parser(data): 
    result = [] 
    for p in data: 
     ms = re.match(r'(\S+).*?(O:\S+).*(R:\S+).*mid:(\d+)', p) 
     if not ms: 
      continue 
     result.append({'Heure':ms.group(1), 'Source':ms.group(2), 'Destination':ms.group(3), 'MID':ms.group(4)}) 
    return result 


data = ["00:02:12.935 mta   Messages  I Doc O:NVS:FAXG3/ R:NVS:SMTP.0/[email protected] mid:6499", 
     "00:03:12.935 mta   Messages  I Doc O:NVS:FAXG3/ R:NVS:SMTP.0/[email protected] mid:6599"] 

print parser(data) 

結果:

>>> 
[{'Source': 'O:NVS:FAXG3/', 'Destination': 'R:NVS:SMTP.0/[email protected]', 'Heure': '00:02:12.935', 'MID': '6499'}, 
{'Source': 'O:NVS:FAXG3/', 'Destination': 'R:NVS:SMTP.0/[email protected]', 'Heure': '00:03:12.935', 'MID': '6599'}] 

作爲發電機:

import re 

def parser(data): 
    for p in data: 
     ms = re.match(r'(\S+).*?(O:\S+).*(R:\S+).*mid:(\d+)', p) 
     if not ms: 
      continue 
     yield {'Heure':ms.group(1), 'Source':ms.group(2), 'Destination':ms.group(3), 'MID':ms.group(4)}  

data = ["00:02:12.935 mta   Messages  I Doc O:NVS:FAXG3/ R:NVS:SMTP.0/[email protected] mid:6499", 
     "00:03:12.935 mta   Messages  I Doc O:NVS:FAXG3/ R:NVS:SMTP.0/[email protected] mid:6599"] 

for r in parser(data): 
    print r 

結果:

>>> 
{'Source': 'O:NVS:FAXG3/', 'Destination': 'R:NVS:SMTP.0/[email protected]', 'Heure': '00:02:12.935', 'MID': '6499'} 
{'Source': 'O:NVS:FAXG3/', 'Destination': 'R:NVS:SMTP.0/[email protected]', 'Heure': '00:03:12.935', 'MID': '6599'} 

使用@mgilsonsanswer的想法與我的正則表達式:

def extract(data): 
    ms = re.match(r'(\S+).*?(O:\S+).*(R:\S+).*mid:(\d+)', data) 
    if not ms: 
     raise Exception('Could not extract data') 
    return {'Heure':ms.group(1), 'Source':ms.group(2), 'Destination':ms.group(3), 'MID':ms.group(4)} 

tableau = [extract(data) for data in data_list] 
+0

謝謝inbar rose糾正我的正則表達式,這樣更好! –

+0

我修復了返回字典。我在ms羣組上犯了一個錯誤。檢查我的編輯。 –

+0

我喜歡你寫REGEX的方式,我對它不是很熟悉,你能告訴我你會怎樣寫一個重試來提取我嘗試過的東西(O:NVS:\ S +),但它會返回所有的值(O:NVS:FAXG3)我希望它只返回FAXG3和同樣的東西(R:NVS:\ S +)我希望它只返回[email protected] 簡而言之,目標是獲得起源消息的類型,它的發送者和目的地消息的類型以及它的目的地,我是否清楚了? –

0

感謝Wooble爲激勵這個While功能和示例。這個想法讓我想到如何去做。

>>> def While(function, *args, **kwargs): 
    while function(*args, **kwargs): pass 


>>> def unstack(array): 
    print(array.pop()) 
    return array 

>>> While(unstack, ['world!', 'there', 'Hello']) 
Hello 
there 
world! 

>>> def fib(state): 
    state.append(sum(state)) 
    print(state.pop(0)) 
    return state[0] < 1000 

>>> While(fib, [0, 1]) 
0 
1 
1 
2 
3 
5 
8 
13 
21 
34 
55 
89 
144 
233 
377 
610 
987 
>>> 

發電機是相當不錯的了,所以一WhileGenerator的創建,以及爲了滿足我的好奇心。

>>> def WhileGenerator(function, *args, **kwargs): 
    iterator = iter(function(*args, **kwargs)) 
    while next(iterator): 
     yield next(iterator) 


>>> import operator, functools, itertools 
>>> for value in WhileGenerator(lambda a, b: functools.reduce(operator.add, 
     itertools.zip_longest(a, b)), 
     (True, True, True, False), 
     'Hello there world!'.split()): 
    print(value) 


Hello 
there 
world! 
>>> def fib_gen(state, limit): 
    while True: 
     yield state[0] < limit 
     state.append(sum(state)) 
     yield state.pop(0) 


>>> for value in WhileGenerator(fib_gen, [0, 1], 1000): 
    print(value) 


0 
1 
1 
2 
3 
5 
8 
13 
21 
34 
55 
89 
144 
233 
377 
610 
987 
>>> 
相關問題