-------------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)。 a
,b
以及某些字段后的其他字母是子字段。
我的代码中带有破折号的行表示输入的年份。每个记录组在---年---开始 - 并在---年---之前的行结束。
此外,fields
是一个列表:
fields=["1", "2", "3,", "4", "5"]
。
我最终会尝试检索每个条目/年的字段旁边的值。例如,如果我的当前字段是1
,相当于fields[0]
,我将遍历所有年份(2000年,2001年和2002年)以获取字段{{1}的值}。输出将是
1
我如何迭代这些年(由破折号表示)?我似乎无法想到生成所需输出的代码。
答案 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