Python使用列表理解读取行(csv和json文件)
我对列表理解在作为csv或json文件读取文件时的用法有疑问。 在第一段代码中,我使用普通的长路径获取一行的值,并在最后将其附加到一个空列表中。正如预期的那样,它工作正常,没有任何问题:Python使用列表理解读取行(csv和json文件),python,json,loops,csv,list-comprehension,Python,Json,Loops,Csv,List Comprehension,我对列表理解在作为csv或json文件读取文件时的用法有疑问。 在第一段代码中,我使用普通的长路径获取一行的值,并在最后将其附加到一个空列表中。正如预期的那样,它工作正常,没有任何问题: with open("file.csv") as W_F: reader = csv.reader(W_F) header = next(reader) brightness,lons,lats=[], [], [] for row in reader:
with open("file.csv") as W_F:
reader = csv.reader(W_F)
header = next(reader)
brightness,lons,lats=[], [], []
for row in reader:
bright=float(row[2])
brightness.append(bright)
lons.append(float(row[0]))
lats.append(float(row[1]))
在这段代码中,我尝试通过使用列表理解来缩小代码,但在这里我遇到了一个问题。对于读卡器中的行,我只获取第一个列表的值brightness=[float(行[2])
。其他列表将被打印为空列表(lon=[float(rows[1])用于读卡器中的行]
和lat=[float(rows[1])用于读卡器中的行]
)
在这里,我在读取json文件时使用列表理解。我可以毫无问题地获取所有值:
with open("file.json")as f:
all_eq_data = json.load(f)
all_eq_dicts = all_eq_data['features']
mag = [dicts["properties"]["mag"] for dicts in all_eq_dicts]
lang = [dicts["geometry"]["coordinates"][0] for dicts in all_eq_dicts]
lat = [dicts["geometry"]["coordinates"][1] for dicts in all_eq_dicts]
有人能给我解释一下为什么第二个代码中的列表理解不能正常工作吗?为什么在第二个代码中,它只在第一个列表中存储值,而不在其他列表中存储值?为什么它在第三个代码中工作,而在第二个代码中不工作?如果我做错了什么,第一个代码和第二个代码之间的区别是什么(注意:第一个和第二个代码使用的是同一个文件)。在迭代器上迭代调用每个项的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法以获取迭代器中的下一项。for循环结束的方式是当\uuuu next\uuu
方法抛出StopIteration
异常时,因为它没有更多的项可提供给您。这个机制“烧掉”了迭代器(也就是说,在迭代结束时,将不再有“下一个”项)
在第二个代码段中,您尝试并迭代整个迭代器,然后在完成之后(当其中没有更多项时),在下面的列表中再次尝试并迭代它
每次对all_eq_data
对象执行for循环时,第三段代码都会创建一个新的迭代器(这是因为它是iterable而不是迭代器(csv.reader是一个迭代器)
总之,第二个代码在迭代器上运行(第一次使用后会耗尽),第二个代码在iterable上运行(每次循环时都返回不同的对象)。
有关迭代器和iterable之间的差异的更多信息。这里纠缠的问题是由于迭代器方法
next()。
现在你需要理解一个简单的概念。for
循环由两部分组成
1。迭代器
2。来电者
迭代器的目的是创建一个迭代对象,而调用方方法的目的是迭代对象(即开始调用对象)。
现在,对于每个迭代器,应该调用一个方法next()
。一旦调用了该方法,对象的缓冲区将被清空,在迭代对象之前必须调用另一个next()
方法
下面的例子将更加清楚:
这里有一个简单的列表
a=[1,2,3,4]
b=iter(a) // Creates an iterator object in memory
next(b) // Starts calling the iterator object which only has one iteration till now
>> 1
next(b)
>> 2
next(b)
>> 3
这正是for循环所做的,而不必显式地生成一个迭代器,每次调用next()
(默认情况下我们会处理这个问题!)
在块的第二部分中,运行
next(reader)
,这是迭代器迭代第一行的调用方方法。当您为读卡器中的行调用brightness=[float(row[2])
时,第一行的缓冲区将被清空,并且在第一行中没有任何东西可以迭代,除非调用next(reader)
方法,该方法将用下一行的数据填充缓冲区!这就是为什么第一个next(reader)
但是,如果要使用next()
获取项目,我建议您解压缩以下值:
with open("file.csv") as W_F:
reader = csv.reader(W_F)
header = next(reader)
lon,lat,brightness=header
只需将这些未打包的值附加到字典或列表中
希望你能理解 谢谢:)我将阅读更多关于iterator、iterable和Iteration的内容。对于列表理解来说,这不是一个好的用例。在第一个代码中,您只在一个for循环中填充了所有列表。在第二段和第三段代码中,您需要三个列表理解,这相当于三个for循环?这不是标准术语。是的,不是。在过去的十年中,
next()
函数没有正式的术语接受。但是,它肯定与面向对象方法调用有关,我认为这对于人们理解其背后的概念非常重要。也许这个评论会让“呼叫者”成为官方术语:-)
for i in range(1,4): // For loop creates an iterator and calls it consecutively!
print(i)
>> 1
>> 2
>> 3
with open("file.csv") as W_F:
reader = csv.reader(W_F)
header = next(reader)
lon,lat,brightness=header