在CSV文件中逐行循环数字
我写了一个Python脚本,用来在PostgreSQL中运行SQL语句,
import sys, os, math
os.chdir(r'C:\Users\Heinz\Desktop')
print os.getcwd()
#set up psycopg2 environment
import psycopg2
#shortest_path module
query = """
select *
from shortest_path ($$
select
gid as id,
source::int4 as source,
target::int4 as target,
cost::double precision as cost,
rcost::double precision as reverse_cost
from network
$$, %s, %s, %s, %s
)
"""
#make connection between python and postgresql
conn = psycopg2.connect("dbname = 'test' user = 'postgres' host = 'localhost' password = 'xxxx'")
cur = conn.cursor()
#count rows in the table
cur.execute("select count(*) from network")
result = cur.fetchone()
k = result[0] + 1 #number of points = number of segments + 1
#run loops
#import csv module
import csv
import tempfile
element = []
i = 1
l = 1
filename = 'pi_value.csv'
with open(filename, 'wb') as f:
while i <= k:
while l <= k:
cur.execute(query, (i, l, True, True))
element = cur.fetchall()
product = sum([a[-1] for a in element[:-1]])
writer = csv.writer(f, delimiter = ',')
writer.writerow([product])
element = []
l = l + 1
l = 1
i = i + 1
你可以看到我使用了从i到k(还有从l到k)的迭代器来做while循环,现在我有一个包含我想要的迭代器i和l的数字的csv文件。例如,这就是我的csv文件,
我希望迭代器能从第一行开始,逐行循环,就像在最里面的while循环中那样,l = 6, l = 31, l = 28,..., l = 17,i也从6开始,但只有在l变到17时,i才会移动到i = 31,然后再回到l = 6,依此类推。
我该怎么写额外的代码来读取这个csv文件,让while循环中的迭代器按照文件里的数字来运行呢?
更新#1
我试了这个,
element = []
with open('tc_sta_id.csv') as f1, open('pi_value.csv', 'wb') as f2:
csvs = csv.reader(f1)
col_num = 0
rows = list(csvs)
k = len(rows)
for row in csvs:
i = row[col_num]
l = row[col_num]
while i <= k:
while l <= k:
cur.execute(query, (i, l, True, True))
element = cur.fetchall()
product = sum([a[-1] for a in element[:-1]])
writer = csv.writer(f2, delimiter = ',')
writer.writerow([product])
element = []
l = l + 1
l = row[col_num]
i = i + 1
脚本运行得很好,但输出的csv文件里全是空白,请给我一些建议来解决这个问题!
3 个回答
我给你做了一个简单的测试,使用了基本的Python功能。
f = open('test.csv')
csvlines = f.readlines()
f.close()
numbers = [int(n.split(',')[0]) for n in csvlines]
你可能需要根据你操作系统的地区设置,把','替换成';'或者其他符号。
简单解释一下: csvlines会包含你的csv文件中的每一行,格式是字符串,比如说 ['1,a,some text', '2,b,some other text']。你会逐行处理这些内容,并对每一行使用split方法,比如说 '1,a,some text'.split(',') 会得到 ['1','a','some text']。你的第一列需要转换成整数,因为它现在还是字符串形式。
在你的代码中使用如下(根据问题的修改进行了编辑):
for i in numbers:
if(i<k):
for l in numbers:
# not sure what your constraint on k is, but you can stop iterating
# through the numbers with a simple if
if(l<k):
#do work (you can use i an l here, they will automatically
# take the next value each iteration of the for loop
#(try print i, l for example): 6,6; 6,31; ...; 6,17; 31,6; 31,31
col_num是你存放i值的那一列的列号。
with open('yourfile') as file:
csv = csv.reader(file)
next(csv) # skip the header
col_num = 0
for row in csv:
i = row[col_num]
while i <= k:
cur.execute(query, (i, 100000000000, True, True))
rs.append(cur.fetchall())
i = i + 1
由于你的问题从一开始就发生了很大变化,我决定单独给你一个回答。这是专门针对你更新的第一个问题的回答。
你的while循环的条件是错误的。你的条件是基于csv文件中的行数(在你的例子中是8)。你把这个行数和csv中找到的数字(比如6、31等)进行比较。这就意味着每次当你遇到第二个数字(31大于8)时,while循环就会停止。此外,你并没有跳到csv中的下一个元素,而只是简单地加1。我没有尝试运行你的代码,但我觉得你是在循环:i=6,7,8,而l也分别是6,7,8。然后它尝试31,立刻停止,因为其他的数字也是大于8的。
我不太确定你想要什么,因为你似乎一直想用额外的while循环来做某些事情,但我不明白你想用它们来做什么(在你的问题中找不到相关信息,所有内容都只暗示使用for循环)。
我也不确定i和l是否来自同一个csv文件。我给你做了一个解决方案,你可以很容易地让i和l来自不同的csv文件,但我一开始设定它们来自同一个。如果它们来自同一个csv,你不能简单地用相同的迭代器嵌套for循环,所以我们采用了一个小技巧,把它们提取到一个列表中(我用一个简单的例子测试过这个)。
rows = list(csvs) #convert to a list to avoid problems with iterating over the same iterator
csv_for_i = rows
csv_for_l = rows
for row_i in csv_for_i:
i = row_i[col_num]
for row_l in csv_for_l:
l = row_l[col_num]
cur.execute(query, (i, l, True, True))
element = cur.fetchall()
product = sum([a[-1] for a in element[:-1]])
writer = csv.writer(f2, delimiter = ',')
writer.writerow([product])
element = []
如果这个方法有效,请告诉我。如果有效,请接受这个回答,我会考虑如何把问题和回答整理得更好,以便在Stack Overflow上更好地使用。目前,这里实际上有多个问题和回答,这对其他寻找答案的人来说很困惑。
顺便说一下,给你一个关于迭代器常见陷阱的小例子(虽然是用csv做的,但适用于所有迭代器)。
import csv
# test.csv contents:
#
#6
#31
#17
print 'Case 1:'
with open('test.csv') as f1:
csv1 = csv.reader(f1)
csv2 = csv.reader(f1)
for el1 in csv1:
for el2 in csv2:
print el1, el2
# Results
#
#['6'] ['31']
#['6'] ['17']
print 'Case 2:'
with open('test.csv') as f1:
csvs = csv.reader(f1)
rows = list(csvs)
for el1 in rows:
for el2 in rows:
print el1, el2
# Results
#
#['6'] ['6']
#['6'] ['31']
#['6'] ['17']
#['31'] ['6']
#['31'] ['31']
#['31'] ['17']
#['17'] ['6']
#['17'] ['31']
#['17'] ['17']
print 'Case 3:'
with open('test.csv') as f1, open('test.csv') as f2:
for el1 in csv.reader(f1):
for el2 in csv.reader(f2):
print el1, el2
# Results
#
#['6'] ['6']
#['6'] ['31']
#['6'] ['17']
print 'Case 4:'
with open('test.csv') as f1, open('test.csv') as f2:
csv1 = csv.reader(f1)
csv2 = csv.reader(f2)
for el1 in csv1:
for el2 in csv2:
print el1, el2
# Results
#
#['6'] ['6']
#['6'] ['31']
#['6'] ['17']