Python:迭代多个级别

时间:2015-06-16 15:44:54

标签: python loops iteration

-------------2000--------------
1        17824
2        20131125192004.9
3        690714s1969    dcu           000 0 eng
4    a       75601809 
4    a    DLC
4    b    eng
4    c    DLC
5    a    WA 750
-------------2001--------------
1        3224
2        20w125192004.9
3        690714s1969    dcu           000 0 eng
5    a    WA 120
-------------2002--------------
2        2013341524626245.9
3        484914s1969    dcu           000 0 eng
4    a       75601809 
4    a    eng
4    c    DLC
5    a    WA 345

我想迭代每年的年份和字段(例如1,2,3,4和5)。 ab以及某些字段后的其他字母是子字段。

我的代码中带有破折号的行表示输入的年份。每个记录组在---年---开始 - 并在---年---之前的行结束。

此外,fields是一个列表: fields=["1", "2", "3,", "4", "5"]

我最终会尝试检索每个条目/年的字段旁边的值。例如,如果我的当前字段是1,相当于fields[0],我将遍历所有年份(2000年,2001年和2002年)以获取字段{{1}的值}。输出将是

1

我如何迭代这些年(由破折号表示)?我似乎无法想到生成所需输出的代码。

2 个答案:

答案 0 :(得分:0)

您可以先使用正则表达式拆分文本,然后在嵌套列表推导中使用itertools.izip_longest来获取预期的列:

>>> import re
>>> blocks=re.split(r'-+\d+-+',s)
>>> from itertools import izip_longest

>>> z=[list(izip_longest(*[k for k in sub if k])) for sub in izip_longest(*[[j.split() for j in i.split('\n')] for i in blocks])]
[[], [('1', '1', '2'), ('17824', '3224', '2013341524626245.9')], [('2', '2', '3'), ('20131125192004.9', '20w125192004.9', '484914s1969'), (None, None, 'dcu'), (None, None, '000'), (None, None, '0'), (None, None, 'eng')], [('3', '3', '4'), ('690714s1969', '690714s1969', 'a'), ('dcu', 'dcu', '75601809'), ('000', '000', None), ('0', '0', None), ('eng', 'eng', None)], [('4', '5', '4'), ('a', 'a', 'a'), ('75601809', 'WA', 'eng'), (None, '120', None)], [('4', '4'), ('a', 'c'), ('DLC', 'DLC')], [('4', '5'), ('b', 'a'), ('eng', 'WA'), (None, '345')], [('4',), ('c',), ('DLC',)], [('5',), ('a',), ('WA',), ('750',)], []]

每个子列表代表每个块中的特定行,例如,第一个子列表是每个块中的第一行:

>>> z=[i for i in z if i] # remove the empty lists
>>> z[0]
[('1', '1', '2'), ('17824', '3224', '2013341524626245.9')]
>>> z[0][1]
('17824', '3224', '2013341524626245.9')

答案 1 :(得分:0)

所以我正在编写一个使用辅助函数的相当复杂的答案,但我认为你会发现它非常灵活。它使用我编写的名为groupby的iterutil类型辅助函数。 groupby函数接受一个键函数来指定每个项目属于哪个组。在你的情况下,关键功能有点花哨,因为它必须保持状态,以了解每个元素属于哪一年。下面的代码是完全可以运行的。只需复制并粘贴到脚本中,让我知道您的想法。

修改

原来,groupby函数已经在itertools模块中实现了,我一直都没想到它。我编辑了代码以使用itertools版本

#!/usr/bin/env python

import io
import re
import itertools as it

data = '''-------------2000--------------
1        17824
2        20131125192004.9
3        690714s1969    dcu           000 0 eng
4    a       75601809 
4    a    DLC
4    b    eng
4    c    DLC
5    a    WA 750
-------------2001--------------
1        3224
2        20w125192004.9
3        690714s1969    dcu           000 0 eng
5    a    WA 120
-------------2002--------------
2        2013341524626245.9
3        484914s1969    dcu           000 0 eng
4    a       75601809 
4    a    eng
4    c    DLC
5    a    WA 345'''

def group_year():
    ''' 
    A stateful closure to group the year blobs together
    ''' 
    # Hack to update a variable from the closure
    g = [0]
    def closure(e):
        if re.findall(r'-----[0-9]{4}------', e): 
            g[0] += 1
        return g[0]
    return closure

if __name__ == "__main__":
    f = io.BytesIO(data)
    gy = group_year()
    for k,group in it.groupby(f, key=gy):
        # group is now an iter of lines for each year group in the data
        # Now you can iterate on each group like so:
        for line in group:
            rec = line.strip().split()
            if rec[0] == '1':
                print rec[1]
        # You could also use nested groupby's at this point to perform
        # further grouping on the different columns or whatever