读取同一个 csv 文件时,嵌套 for 循环在 python 中不起作用
Nested for loop doesn't work in python while reading a same csv file
我是 python 的初学者,并试图通过谷歌搜索找到解决方案。但是,我找不到任何我想要的解决方案。
我想用 python 做的是对数据进行预处理,以查找关键字并从大型 csv 文件中获取包含关键字的所有行。
并且嵌套循环以某种方式经历了 just once
然后它没有经历 second loop
。
下面显示的代码是我从 csv
文件中查找关键字并写入文本文件的代码的一部分。
def main():
#Calling file (Directory should be changed)
data_file = 'dataset.json'
#Loading data.json file
with open(data_file, 'r') as fp:
data = json.load(fp)
#Make the list for keys
key_list = list(data.keys())
#print(key_list)
preprocess_txt = open("test_11.txt", "w+", -1, "utf-8")
support_fact = 0
for i, k in enumerate(key_list):
count = 1
#read csv, and split on "," the line
with open("my_csvfile.csv", 'r', encoding = 'utf-8') as csvfile:
reader = csv.reader(csvfile)
#The number of q_id is 2
#This is the part that the nested for loop doesn't work!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if len(data[k]['Qids']) == 2:
print("Number 2")
for m in range(len(data[k]['Qids'])):
print(len(data[k]['Qids']))
q_id = [data[k]['Qids'][m]]
print(q_id)
for row in reader: #--->This nested for loop doesn't work after going through one loop!!!!!
if all([x in row for x in q_id]):
print("YES!!!")
preprocess_txt.write("%d %s %s %s\n" % (count, row[0], row[1], row[2]))
count += 1
以上代码的详细信息,
首先,它从 data.json
文件中提取所有键,然后将这些键放入列表(key_list
).
其次,我使用all([x in row for x in q_id])
方法检查包含关键字(q_id
)的每一行。
然而,正如我在上面的代码中评论的那样,当 data[k]['Qids']
的长度为 2 时,它会在第一个循环中正确打印出 YES!!!
,但不会打印出 YES!!!
在第二个循环中,这意味着它不会进入 for row in reader
循环,即使该 csv 文件包含关键字。
打印图如下,
我做错了什么..?或者我应该为代码添加什么才能使其正常工作..?
谁能帮帮我..?
感谢观看!
我相信你的 reader 变量只包含你的 csv 文件的第一行,因此 for row in reader
只执行一次。
尝试:
with open("my_csvfile.csv", newline='', 'r', encoding = 'utf-8') as csvfile:
newline=''
就是上面介绍的新参数。
参考:https://docs.python.org/3/library/csv.html#id3
Quote: "如果 csvfile 是一个文件对象,它应该用 newline=''
打开
举个例子,假设我有一个如下所示的 CSV 文件:
foods.csv
beef,stew,apple,sauce
apple,pie,potato,salami
tomato,cherry,pie,bacon
和下面的代码,这是为了模拟您当前代码的结构:
def main():
import csv
keywords = ["apple", "pie"]
with open("foods.csv", "r") as file:
reader = csv.reader(file)
for keyword in keywords:
for row in reader:
if keyword in row:
print(f"{keyword} was in {row}")
print("Done")
main()
期望的结果是,对于我的关键字列表中的每个关键字,如果该关键字存在于我的 CSV 文件的某一行中,我将在屏幕上打印一个字符串 - 指示该关键字在哪一行发生了。
但是,这里是实际输出:
apple was in ['beef', 'stew', 'apple', 'sauce']
apple was in ['apple', 'pie', 'potato', 'salami']
Done
>>>
它能够在文件中找到关键字 apple
的两个实例,但没有找到 pie
!那么,给出了什么?
问题
file
句柄(在您的例子中是 csvfile
)产生一次它的内容,然后它们被消耗掉。我们的 reader
对象环绕文件句柄并消耗其内容,直到它们被耗尽,此时将没有剩余行可从文件中读取(内部文件指针已前进到末尾),并且内部for循环不会执行第二次。
解决方法
在外部 for 循环的每次迭代后使用 seek
将内部文件指针移动到开头,或者将文件内容一次读入列表或类似集合,然后迭代改为列表:
更新代码:
def main():
import csv
keywords = ["apple", "pie"]
with open("foods.csv", "r") as file:
contents = list(csv.reader(file))
for keyword in keywords:
for row in contents:
if keyword in row:
print(f"{keyword} was in {row}")
print("Done")
main()
新输出:
apple was in ['beef', 'stew', 'apple', 'sauce']
apple was in ['apple', 'pie', 'potato', 'salami']
pie was in ['apple', 'pie', 'potato', 'salami']
pie was in ['tomato', 'cherry', 'pie', 'bacon']
Done
>>>
我是 python 的初学者,并试图通过谷歌搜索找到解决方案。但是,我找不到任何我想要的解决方案。
我想用 python 做的是对数据进行预处理,以查找关键字并从大型 csv 文件中获取包含关键字的所有行。
并且嵌套循环以某种方式经历了 just once
然后它没有经历 second loop
。
下面显示的代码是我从 csv
文件中查找关键字并写入文本文件的代码的一部分。
def main():
#Calling file (Directory should be changed)
data_file = 'dataset.json'
#Loading data.json file
with open(data_file, 'r') as fp:
data = json.load(fp)
#Make the list for keys
key_list = list(data.keys())
#print(key_list)
preprocess_txt = open("test_11.txt", "w+", -1, "utf-8")
support_fact = 0
for i, k in enumerate(key_list):
count = 1
#read csv, and split on "," the line
with open("my_csvfile.csv", 'r', encoding = 'utf-8') as csvfile:
reader = csv.reader(csvfile)
#The number of q_id is 2
#This is the part that the nested for loop doesn't work!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if len(data[k]['Qids']) == 2:
print("Number 2")
for m in range(len(data[k]['Qids'])):
print(len(data[k]['Qids']))
q_id = [data[k]['Qids'][m]]
print(q_id)
for row in reader: #--->This nested for loop doesn't work after going through one loop!!!!!
if all([x in row for x in q_id]):
print("YES!!!")
preprocess_txt.write("%d %s %s %s\n" % (count, row[0], row[1], row[2]))
count += 1
以上代码的详细信息,
首先,它从 data.json
文件中提取所有键,然后将这些键放入列表(key_list
).
其次,我使用all([x in row for x in q_id])
方法检查包含关键字(q_id
)的每一行。
然而,正如我在上面的代码中评论的那样,当 data[k]['Qids']
的长度为 2 时,它会在第一个循环中正确打印出 YES!!!
,但不会打印出 YES!!!
在第二个循环中,这意味着它不会进入 for row in reader
循环,即使该 csv 文件包含关键字。
打印图如下,
我做错了什么..?或者我应该为代码添加什么才能使其正常工作..?
谁能帮帮我..?
感谢观看!
我相信你的 reader 变量只包含你的 csv 文件的第一行,因此 for row in reader
只执行一次。
尝试:
with open("my_csvfile.csv", newline='', 'r', encoding = 'utf-8') as csvfile:
newline=''
就是上面介绍的新参数。
参考:https://docs.python.org/3/library/csv.html#id3
Quote: "如果 csvfile 是一个文件对象,它应该用 newline=''
举个例子,假设我有一个如下所示的 CSV 文件:
foods.csv
beef,stew,apple,sauce
apple,pie,potato,salami
tomato,cherry,pie,bacon
和下面的代码,这是为了模拟您当前代码的结构:
def main():
import csv
keywords = ["apple", "pie"]
with open("foods.csv", "r") as file:
reader = csv.reader(file)
for keyword in keywords:
for row in reader:
if keyword in row:
print(f"{keyword} was in {row}")
print("Done")
main()
期望的结果是,对于我的关键字列表中的每个关键字,如果该关键字存在于我的 CSV 文件的某一行中,我将在屏幕上打印一个字符串 - 指示该关键字在哪一行发生了。
但是,这里是实际输出:
apple was in ['beef', 'stew', 'apple', 'sauce']
apple was in ['apple', 'pie', 'potato', 'salami']
Done
>>>
它能够在文件中找到关键字 apple
的两个实例,但没有找到 pie
!那么,给出了什么?
问题
file
句柄(在您的例子中是 csvfile
)产生一次它的内容,然后它们被消耗掉。我们的 reader
对象环绕文件句柄并消耗其内容,直到它们被耗尽,此时将没有剩余行可从文件中读取(内部文件指针已前进到末尾),并且内部for循环不会执行第二次。
解决方法
在外部 for 循环的每次迭代后使用 seek
将内部文件指针移动到开头,或者将文件内容一次读入列表或类似集合,然后迭代改为列表:
更新代码:
def main():
import csv
keywords = ["apple", "pie"]
with open("foods.csv", "r") as file:
contents = list(csv.reader(file))
for keyword in keywords:
for row in contents:
if keyword in row:
print(f"{keyword} was in {row}")
print("Done")
main()
新输出:
apple was in ['beef', 'stew', 'apple', 'sauce']
apple was in ['apple', 'pie', 'potato', 'salami']
pie was in ['apple', 'pie', 'potato', 'salami']
pie was in ['tomato', 'cherry', 'pie', 'bacon']
Done
>>>