2013-04-17 11 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 
>>> 
相关问题