我一直在试图弄清楚如何使用for
循环和python中给出的enumerate
对象来实现这一点。我有一个HH:MM
格式的时间。我有一个csv文件,其中第一列是遵循相同格式的时间戳。然后,我在文件中搜索匹配的时间,然后提取该行,稍后将其转换为XML文件。但是,我需要提取目标行之前的行和目标行之后的行。我试过下面这段代码:
def findRow(timeID, filename):
rows = []
csvFile = csv.reader(open(filename, "rb"), delimiter=",")
for i, row in enumerate(csvFile):
if timeID == timeInRow:
rows.append(i-1)
rows.append(i)
rows.append(i+1)
return rows
然而,不久之后,我意识到这不是正确的方法,因为我提取的是索引而不是值。我需要的是像rowi-1,rowi,rowi+1这样的东西,换句话说,我需要与行匹配的i的元素。
有什么简单的方法可以做到这一点吗?我曾考虑过使用range(csvFile)
,但老实说,我不知道这会导致什么结果。
发布于 2018-07-14 05:38:36
为此,您可以使用deque。
给定:
$ cat /tmp/file.csv
firstName,lastName,email,phoneNumber
John,Doe,john@doe.com,0123456789
Jane,Doe,jane@doe.com,9876543210
James,Bond,james.bond@mi6.co.uk,0612345678
假设您想要包含Jane
的代码行以及前后的代码行。
尝试:
import csv
from collections import deque
dq=deque([[None] for _ in range(3)],maxlen=3)
with open(fn,'r') as f:
for row in csv.reader(f):
dq.append(row)
if dq[-2][0]=='Jane': break # here you can use your custom function
然后:
>>> dq
deque([['John', 'Doe', 'john@doe.com', '0123456789'], ['Jane', 'Doe', 'jane@doe.com', '9876543210'], ['James', 'Bond', 'james.bond@mi6.co.uk', '0612345678']], maxlen=3)
发布于 2018-07-14 05:47:56
以上方法的替代(函数)方法是使用zip
或其变体。类似于:
rows = list(csv.reader(f))
for x, y, z in zip(rows, rows[1:], rows[2:]):
# y is the middle row, x is above it, and z below it
pass
如果您希望将迭代中的前两行和最后两行包括为
(None, None, rows[0])
(None, rows[0], rows[1])
(rows[-2], rows[-1], None)
(rows[-1], None, None)
然后,您必须在rows
列表的前后两端分别添加两个None。
并不是说这一定比其他答案更好,但这是我会考虑写作的另一种方法。
编辑
根据让-弗朗索瓦的建议使用itertools.islice:
rows = list(csv.reader(f))
from itertools import islice
for x, y, z in zip(rows, islice(rows, 1, None), islice(rows, 2, None)):
# y is the middle row, x is above it, and z below it
pass
https://stackoverflow.com/questions/51333007
复制相似问题