Python 在具有匹配属性的列表中查找第一个和最后一个列表
长期潜伏者,第一次海报 我有一个非常大的文本文件(1184834行),其中包含一些关于欧洲某一天飞行计划的信息。每一列代表一个新键,每一行代表航班的一个新段。到目前为止,我已成功地使用以下代码将分析所需的数据提取到列表中:Python 在具有匹配属性的列表中查找第一个和最后一个列表,python,list,find,Python,List,Find,长期潜伏者,第一次海报 我有一个非常大的文本文件(1184834行),其中包含一些关于欧洲某一天飞行计划的信息。每一列代表一个新键,每一行代表航班的一个新段。到目前为止,我已成功地使用以下代码将分析所需的数据提取到列表中: import pprint import csv pp = pprint.PrettyPrinter(width=200) text = open('E:/Downloads/TNFL09/20120506_m1.so6', 'r') def clean_data(tex
import pprint
import csv
pp = pprint.PrettyPrinter(width=200)
text = open('E:/Downloads/TNFL09/20120506_m1.so6', 'r')
def clean_data(text, rows):
newlist = []
reader = list(csv.reader(text, delimiter=' '))
for n in xrange(0, len(reader)):
newlist.append(reader[n][1:6]+reader[n][9:12]+reader[n][16:18])
return newlist[:rows]
data = clean_data(text,90)
pp.pprint(data)
输出如下所示:
['KEWR','VABB','B772','005500','010051','UAL48','120506','120506','156912546','1']
['KEWR','VABB','B772','010051','010310','UAL48','120506','120506','156912546','2']
这个问题的有趣项是开始/结束时间(#3和#4)、航班ID(#8)和序列号(#9)
每个航班由若干个连续的序列号组成。因此,要获得整个航班,必须提取该航班ID的所有序列号
我想做的是提取每个航班的开始和结束时间。我最初的想法是循环遍历列表中的每个列表,并将序列号与之前迭代的列表进行比较。然而,我是Python的初学者,在谷歌搜索了几天后就放弃了
谢谢
Peter一种方法是,假设您的列表是按序列号排序的(看起来是这样的),则通过生成器将其运行,以将每个航班聚合在一起:
def aggregate_flights(flights):
out = []
last_id = ''
for row in flights:
if row[-2] != last_id and len(out) > 0:
yield (last_id,out)
out = []
last_id = row[-2]
out.append((row[3],row[4])) #2-tuple of (start,end)
yield (last_id,out)
这为您的示例输入提供了:
list(aggregate_flight(agg))
Out[21]:
[('156912756', [('083914', '084141')]),
('156912546', [('005500', '010051'), ('010051', '010310')])]
有点乱,但你明白了。对于每个航班,您将有一个2元组的(开始,结束)
列表,您可以进一步处理该列表以获得该航班的总体(开始,结束)
。您甚至可以修改生成器,只为您提供总体的(开始,结束)
,但我倾向于在较小的模块化块中进行处理,这些块易于调试
如果输入未排序,则需要使用defaultdict
累积数据。给它一个列表
工厂,并为每行追加一个(开始,结束)
元组
编辑:根据要求,这里的修改只产生一个(开始、结束)
对每个航班:
def aggregate_flights(flights):
last_id,start,end = None,None,None
for row in flights:
if row[-2] != last_id and last_id is not None:
yield (last_id,(start,end))
start,end = None,None
if start is None:
start = row[3]
last_id = row[-2]
end = row[4]
yield (last_id,(start,end))
在这一点上,我要注意的是,输出变得太难看了,无法遵守(一个(id,(start,end))
元组,呃),所以我要升级到命名元组,使事情变得更好:
from collections import namedtuple
Flight = namedtuple('Flight',['id','start','end'])
现在你有了:
def aggregate_flights(flights):
last_id,start,end = None,None,None
for row in flights:
if row[-2] != last_id and last_id is not None:
yield Flight(last_id,start,end)
start,end = None,None
if start is None:
start = row[3]
last_id = row[-2]
end = row[4]
yield Flight(last_id,start,end)
list(aggregate_flights(agg))
Out[18]:
[Flight(id='156912756', start='083914', end='084141'),
Flight(id='156912546', start='005500', end='010310')]
更好。我无法判断您的列表是否已按flightID和序列号排序,为此,您可以在列表上执行以下操作:
from operator import itemgetter
#use sort if the original list is not necessary to maintain,
#if it is use sorted and send it to a new variable
flightInfo.sort(key = itemgetter(8,9))
以上内容首先按航班号排序,然后按序列号排序。要提取所需内容,您可以执行以下操作:
prev, startTime = None, None
results = []
for i, info in enumerate(flightInfo):
if prev == None or prev != flight[8]:
if prev != None:
# use a list if you are going to have to modify these values
results.append((prev, startTime, flightInfo[i-1][4]))
startTime = flight[3]
prev = flight[8]
您可以使用map关键字。作为“完整列表”,航班列表:
# python.py
time = [] # Is a dictionaries list. Each dictionary contains: {flight_id: [start, end]}
result = [] # We going to store results here.
def extract(flight, result):
""" param flight: list containing flight's data. """
global result # Give function access to result variable.
# If not, "result" is passed as a value copy.
result.append({flight[9]: [flight[3], flight[3]]})
map(extract, result)
索引1和索引2分别看起来像目的地机场代码和飞机类型。你是说开始/结束时间是3和4吗?而且,没有指数10;python使用基于0的索引。在这个特定上下文中,“键”是什么意思?它是不同的航班吗?它们是否已经按航班ID和/或序列号排序?roippi,是的,你是对的。是的;Dep机场、arr机场、飞机、开始时间、结束时间、呼号、开始日期、结束日期、航班ID、序列我不确定它是按什么排序的,但在每个航班ID中它是按序列号排序的。每个关键点都是一个新的部分。对于每个新的片段=序列+1,如果它不是序列中的第一个。对不起,我没有完全理解这里。关于这个语法,你能在pyth文档中给我指出正确的方向吗?@PeterAxelsson哪个部分?输出?生成器表达式?我不太熟悉生成器。在你的回答之后,我试着读了一点以便更好地理解,但我仍然不太清楚如何使用它们。如果这对你来说不太麻烦的话,我希望能在上面的代码中一步一步的解释。谢谢你的回复,我刚想出来。但是如何修改它(或创建一个新的生成器)以仅提取第一个和最后一个开始/结束对@罗比