【问题标题】:Python for loop unreasonably stops half way while iterating through CSV rowsPython for 循环在遍历 CSV 行时不合理地停止中途
【发布时间】:2017-03-19 08:05:23
【问题描述】:

我正在处理一个CSV文件来分析讲座反馈数据,格式是这样的

"5631","18650","10",,,"2015-09-18 09:35:11"
"18650","null","10",,,"2015-09-18 09:37:12"
"18650","5631","10",,,"2015-09-18 09:37:19"
"58649","null","6",,,"2015-09-18 09:38:13"
"45379","31541","10","its friday","nothing yet keep it up","2015-09-18 09:39:46"

我正在尝试删除不良数据。只有具有 "id1","id2" AND 另一个对应的 "id2","id1" 的数据条目才被认为是有效的。

我正在使用嵌套循环来尝试为每一行查找匹配的条目。但是,外部循环似乎无缘无故地停止了一半。这是我的代码

class Filter:
    file1 = open('EncodedPeerInteractions.FA2015.csv')
    peerinter = csv.reader(file1,delimiter=',') 
    def __init__(self):
        super()

    def filter(self):
        file2 = open('FilteredInteractions.csv','a')
        for row in self.peerinter:
            print(row)
            if row[0] == 'null' or row[1] == 'null':
                continue
            id1 = int(row[0])
            id2 = int(row[1])
            for test in self.peerinter:
                if test[0] == 'null' or test[1] == 'null':
                    continue
                if int(test[0]) == id2 and int(test[1]) == id1:
                    file2.write("\n")
                    file2.write(str(row))
                    break
        file2.close()

我尝试使用 pdb 来逐步执行代码,前几个循环一切都很好,然后突然跳转到 file2.close() 并返回。该程序确实会打印出一些有效的条目,但还不够。

我测试了 csv 文件并将其正确加载到内存中,其中包含超过 18000 个条目。我使用 print 进行了测试,但它给出了相同的结果,所以附加文件没有问题。

编辑

现在我明白问题所在了。正如this question 所说,当有匹配时我会中断,但当没有匹配时,内部循环将消耗所有文件而不重置它。当它返回到外循环时,它就结束了。我应该把它做成一个列表或者让它重置。

【问题讨论】:

  • 快速提问,你为什么要为此使用一个类并调用super()?你在用python 3吗?
  • 老实说,我不知道。有人告诉我,在文件中明确逻辑是不好的。它们应该被封装在类中,在那里放一个 pass 感觉很奇怪。你建议我怎么做?
  • 与上述问题相关 - 你的 Filter 类的父级是什么?不要这样做file1 = open('EncodedPeerInteractions.FA2015.csv'),为了安全,请这样做with open('EncodedPeerInteractions.FA2015.csv',"r") as file1
  • @Bobby 可以编写脚本,只是做一些事情。

标签: python python-3.x csv for-loop


【解决方案1】:

您正在使这种方式变得更加复杂。

给定:

$ cat /tmp/so.csv
"5631","18650","10",,,"2015-09-18 09:35:11"
"18650","null","10",,,"2015-09-18 09:37:12"
"18650","5631","10",,,"2015-09-18 09:37:19"
"58649","null","6",,,"2015-09-18 09:38:13"
"45379","31541","10","its friday","nothing yet keep it up","2015-09-18 09:39:46"

你可以使用 csv 和 filter 来得到你想要的:

>>> with open('/tmp/so.csv') as f:
...    list(filter(lambda row: 'null' not in row[0:2], csv.reader(f)))
... 
[['5631', '18650', '10', '', '', '2015-09-18 09:35:11'], 
 ['18650', '5631', '10', '', '', '2015-09-18 09:37:19'], 
 ['45379', '31541', '10', 'its friday', 'nothing yet keep it up', '2015-09-18 09:39:46']]

【讨论】:

  • 我认为这个方法只是去掉空值,如果一个条目说'123,','234',x,x,x没有对应的'234','123',y,y,y也被认为是无效的
  • 然后将lambda重写为一个测试函数,在每一行测试你的条件...
【解决方案2】:

尝试执行以下操作:

def filter(file1, file2):
    with open(file1, 'r') as f1:
      peerinter = csv.reader(file1,delimiter=',') 
      with open(file2, 'a') as f2:
        for row in peerinter:
        ...

使用with open() 语法将其包装在上下文管理器中,这将确保文件在最后正确关闭。我猜您的问题源于您将一个文件作为类变量打开,另一个在方法内打开。

【讨论】:

    猜你喜欢
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 2016-06-21
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 2017-04-15
    • 2017-01-23
    相关资源
    最近更新 更多