【问题标题】:How to use "While()" in python [closed]如何在 python 中使用“While()”[关闭]
【发布时间】:2013-04-10 05:42:55
【问题描述】:

您好,我下面的所有代码都允许我从数据中提取一些特定信息,我希望有人可以帮助我使用一段时间来更正确地编写此代码,因此我可以为多行执行此操作,现在我只有两行(数据)我是初学者,所以如果有人可以帮助请解释一下,这样我就可以学习,而不仅仅是复制和粘贴=)

#!/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/xxxx@x.fr 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/xxxxx@xxxxx.fr 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 

【问题讨论】:

  • while 是 Python 关键字,没有“While()”函数。 (此外,您可能需要在此处使用 for 循环,因为您正在迭代一组特定的数据。)
  • 我不认为'while'是你想要的。据我了解,通常您会将“数据”作为字符串列表。在这种情况下,您将使用“for..in..”循环
  • 澄清你的问题 - 不清楚你想循环什么。
  • 一些小技巧:把你的数据整理成一个列表;使用 for 循环遍历列表;提取结果并将其附加到每次迭代的表格中。不需要改变太多,所以我相信你能解决它。如果您遇到问题,有很多在线教程。
  • FWIW,result1 = {}result2 = {} 是不必要的。

标签: python regex python-2.7 python-2.x


【解决方案1】:

感谢 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
>>> 

【讨论】:

    【解决方案2】:

    这里。这会以一种更有效的方法解析您的数据,它使用一个函数,您也可以只提供数据列表。如果你想把它变成一个生成器也很容易。

    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/xxxx@x.fr mid:6499",
            "00:03:12.935 mta         Messages       I Doc O:NVS:FAXG3/ R:NVS:SMTP.0/xxxxx@xxxxx.fr mid:6599"]
    
    print parser(data)
    

    结果:

    >>> 
    [{'Source': 'O:NVS:FAXG3/', 'Destination': 'R:NVS:SMTP.0/xxxx@x.fr', 'Heure': '00:02:12.935', 'MID': '6499'},
    {'Source': 'O:NVS:FAXG3/', 'Destination': 'R:NVS:SMTP.0/xxxxx@xxxxx.fr', '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/xxxx@x.fr mid:6499",
            "00:03:12.935 mta         Messages       I Doc O:NVS:FAXG3/ R:NVS:SMTP.0/xxxxx@xxxxx.fr mid:6599"]
    
    for r in parser(data):
        print r
    

    结果:

    >>> 
    {'Source': 'O:NVS:FAXG3/', 'Destination': 'R:NVS:SMTP.0/xxxx@x.fr', 'Heure': '00:02:12.935', 'MID': '6499'}
    {'Source': 'O:NVS:FAXG3/', 'Destination': 'R:NVS:SMTP.0/xxxxx@xxxxx.fr', 'Heure': '00:03:12.935', 'MID': '6599'}
    

    在我的正则表达式中使用@mgilsons answer 想法:

    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] 
    

    【讨论】:

    • 感谢 inbar rose 纠正我的正则表达式,这样更好!
    • 我修复了返回字典。我在 ms 组上犯了一个错误。检查我的编辑。
    • 我喜欢你写 REGEX 的方式,我不是很熟悉,你能告诉我你会如何写一个 re 来提取我试过之后的内容(O:NVS:\ S+) 但它返回所有值 (O:NVS:FAXG3) 我希望它只返回 FAXG3 和相同的东西 (R:NVS:\S+) 我希望它只返回 xxxx@x.fr简而言之,目标是获取原始消息的类型及其发件人以及目标消息的类型及其目的地,我是否足够清楚?
    • 欢迎大家提出新问题,如何制作更高效的正则表达式,也可以自己试试。请咨询docs 或使用this site 作为开始的好地方。
    • 好的,我会自己尝试,如果我不成功,我会问一个问题,无论如何谢谢你的时间;)
    【解决方案3】:

    这实际上用for loop 做得更好:

    data1 = "00:02:12.935 mta         Messages       I Doc O:NVS:FAXG3/ R:NVS:SMTP.0/xxxx@x.fr mid:6499"
    data2 = "00:03:12.935 mta         Messages       I Doc O:NVS:FAXG3/ R:NVS:SMTP.0/xxxxx@xxxxx.fr 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})
    

    更高级的用户可能会在这里使用一个函数,该函数将字符串作为输入并返回所需数据的字典:

    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]
    

    从 cmets 看来,您正在从文件中获取数据行。那更好(谁想输入所有这些字符串?)。现在我们可以将其缩短为:

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

    使用with 引入了另一个python 结构——(上下文管理器)。这有点复杂,但它是打开文件的首选方式。对于文件对象,它在功能上等同于:

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

    【讨论】:

    • 这是解决问题的好方法,但是 - 我建议在我的答案中使用正则表达式,因为它更快。
    • 是的,但我不能在 python 2.6 中使用它:/
    • 当然——我什至没有看正则表达式。最终,我希望 OP 学习一些关于 python 的知识。而且您有一个可变的默认参数(这对您的函数来说很好,但如果 OP 采用该习语并在任何地方使用它可能不是一个好主意)
    【解决方案4】:

    我不认为 while 是做你所期望的最好的方法。也许你可以使用

    for data in dataArray: 
    

    dataArray 包含您的数据字符串的位置。

    【讨论】:

      猜你喜欢
      • 2019-07-01
      • 2012-11-20
      • 2013-03-11
      • 1970-01-01
      • 1970-01-01
      • 2018-09-10
      • 2018-07-30
      • 2014-11-24
      • 2018-08-15
      相关资源
      最近更新 更多