循环使用csv文件的行中的数字

时间:2014-06-13 13:32:03

标签: python loops csv while-loop iterator

我编写了一个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循环,现在我得到了一个包含数字的csv文件我希望 iterator i和l 是。例如,这是csv文件,

enter image description here

我希望迭代器循环使用从第一行开始的每一行中的数字,就像在最里面的while循环中一样, l = 6,l = 31,l = 28,...,l = 17,我也从6开始,但只移动到i = 31,因为l移动到17并返回到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 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

由于你的问题从一开始就有了很大的改变,我只是将其作为一个单独的答案添加。所以这是一个专门针对您的更新1的答案。

你的while循环的条件是错误的。您的条件基于csv中的行数(示例中为8)。你将它与csv中的数字进行比较(所以6,31,...)。这意味着每次敲击第二个数字(31> 8)时,while循环都会停止。此外,你没有跳到你的csv的下一个元素,但你只是添加1.我没有尝试运行你的代码,但我认为你的循环:i = 6,7,8,l = 6,7 ,每个i的值为8。然后它尝试31,立即停止,与其余的一样(它们都超过8)。

我不完全确定你想要什么,因为你似乎一直想要使用额外的while循环,我不确定你想要使用它们(在你的问题中找不到它,一切在你的问题中仅暗示循环)。

我也不确定我和我是否来自同一个csv。我为你制作了一个解决方案,你可以轻松地让我和我来自不同的csvs,但我在开始时设置它们来自同一个。如果它们来自相同的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 = []

如果有效,请告诉我。如果是这样,接受答案,我会考虑如何将问题和答案转化为更好地处理堆栈溢出的问题。目前,这里实际上存在多个问题和答案,这对于寻找答案的其他人来说很困惑。


仅供参考,一个关于迭代器陷阱的小例子(用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']

答案 2 :(得分:0)

我使用简单的python功能为您做了一个简短的测试。

f = open('test.csv')
csvlines = f.readlines()
f.close()
numbers = [int(n.split(',')[0]) for n in csvlines]

您可能需要更换&#39;,&#39;用&#39;;&#39;或其他内容,具体取决于操作系统的区域设置。

简短说明: csvlines将包含csv的行作为字符串,f.e。 [&#39; 1,a,某些文字&#39;,&#39; 2,b,其他一些文字&#39;]。您将遍历这些行并在线路上调用split,例如&#39; 1,a,某些文字&#39; .split(&#39;,&#39;)会给出[&#39; 1&#39;,&#39; a&#39;,&#39; ;一些文字&#39;]。然后,您的第一列将需要转换为整数,因为它当前仍是一个字符串。

在代码中使用(编辑为问题已编辑):

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