首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >找到匹配的Python CSV读取器搜索字符串

找到匹配的Python CSV读取器搜索字符串
EN

Stack Overflow用户
提问于 2018-08-04 02:55:35
回答 2查看 60关注 0票数 0

带着另一个问题再次回来。

前言:使用Qt Designer,搜索按钮,解析csv数据,并使用找到的数据构建我的TableWidget。

我有一个文件,它有两个相似的结果,例如,一个位置被标记为Reddit (North)和Reddit (South)。如果我搜索Reddit,只显示第一个结果,但当我再次按下搜索按钮时,它只显示第一个查找,而不是第二个。

问题:如何在第一次匹配时停止csv阅读器,在表格中填入从第一次命中找到的数据,然后再次点击搜索按钮以清除第一次命中并显示第二次命中?

代码语言:javascript
复制
def search(self):
    self.table_search.setRowCount(6)
    self.table_search.setColumnCount(1)
    self.table_search.verticalHeader().setDefaultSectionSize(20)
    self.table_search.verticalHeader().setVisible(True)
    self.table_search.setVerticalHeaderLabels([
                            'Location ID:', 
                            'Location Name:', 
                            'Cost Center:', 
                            'Street Address:', 
                            'City:', 
                            'State:']
    )

    # taking input from a PyQt line edit box
    search = self.lineedit_locsearch.text()
    search_string = search.strip().upper() # stripping white space from the string

    # containers for specific data from the csv file
    locid = ''
    locname = ''
    loccost = ''
    locaddress = ''
    loccity = ''
    locstate = ''

    with open('data/loc.csv', "r") as locdata:
        reader = csv.reader(locdata)

        for row in reader: 
            for field in row: 
                if field == search_string: 
                    locid = row[0]
                    locname = row[1]
                    loccost = row[2]
                    locaddress = row[3]
                    loccity = row[4]
                    locstate = row[5]

    locdata.close()


    self.table_locsearch.setItem(0, 0, QtWidgets.QTableWidgetItem(locid))
    self.table_locsearch.setItem(1, 0, QtWidgets.QTableWidgetItem(locname))
    self.table_locsearch.setItem(2, 0, QtWidgets.QTableWidgetItem(loccost))
    self.table_locsearch.setItem(3, 0, QtWidgets.QTableWidgetItem(locaddress))
    self.table_locsearch.setItem(4, 0, QtWidgets.QTableWidgetItem(loccity))
    self.table_locsearch.setItem(5, 0, QtWidgets.QTableWidgetItem(locstate))
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-04 03:47:07

您可以将您的CSV读取/搜索外部化,并使其成为生成器,以便它记住它停止的位置,即:

代码语言:javascript
复制
@staticmethod
def search_csv(path, search):
    with open(path, "r") as f:
        for row in csv.reader(f):
            if search in row:
                yield row

现在,您可以使用它作为搜索迭代器来遍历搜索结果。实际的使用率可能取决于您如何实现系统的其余部分-最好的做法是,如果当前搜索迭代器可用(并且搜索字符串没有更改),则只保留对它的引用,否则创建一个新的迭代器。例如,对您的search()方法进行就地更改以启用它:

代码语言:javascript
复制
def search(self):
    # you could externalize the table setup as it's always static
    self.table_search.setRowCount(6)
    self.table_search.setColumnCount(1)
    self.table_search.verticalHeader().setDefaultSectionSize(20)
    self.table_search.verticalHeader().setVisible(True)
    self.table_search.setVerticalHeaderLabels([
        'Location ID:',
        'Location Name:',
        'Cost Center:',
        'Street Address:',
        'City:',
        'State:'])

    search = self.lineedit_locsearch.text().strip().upper()  # get the current search string
    search_gen = getattr(self, "_search_gen", None)  # attempt to grab the current search
    if search_gen is None or search_gen["search"] != search:  # we need a new search
        search_gen = {"generator": self.search_csv("data/loc.csv", search), 
                      "search": search}   # store the search string as well
        setattr(self, "_search_gen", search_gen)  # save it to the object
    try:
        result = next(search_gen["generator"])
    except StopIteration:  # no (more) results
        result = []  # alternatively you may show that there are no (more) results

    # to ensure validity, let's force the `result` to have at least 6 fields:
    result += [""] * (6 - len(result))  # fill the non-populated fields with empty strings

    for row in range(6):  # fill the table iteratively
        self.table_locsearch.setItem(row, 0, QtWidgets.QTableWidgetItem(result[row]))

它本质上是检查当前实例上是否已经有一个_search_gen字典,以及它是否包含与self.lineedit_locsearch中相同的搜索字符串-如果是,则使用现有的生成器继续搜索CSV,如果没有,则创建一个新的。无论采用哪种方式,生成器都用于获取(下一个)结果,然后填充表。另外,我们确保结果至少有6个字段,这样即使找到的CSV行没有全部6个字段,也可以正确填充该表。

不过,我不确定您是否需要一直重新配置该表-也许您可以在创建搜索结果窗口/面板/框架/其他内容时创建它,然后继续调用search()方法来更新结果。

最后,当您想要关闭搜索时,请确保使用delattr(self, "_search_gen")使生成器无效。还要注意,在搜索期间,传递的文件(data/loc.csv)将在读取模式下保持打开状态,直到找不到更多的结果,或者您如前所述使搜索生成器失效。

票数 0
EN

Stack Overflow用户

发布于 2018-08-04 03:55:34

要跳出这个循环,请尝试下面的代码

代码语言:javascript
复制
breakflag = False
with open('data/loc.csv', "r") as locdata:
    reader = csv.reader(locdata)

    for row in reader:
        if breakflag:
            break
        for field in row: 
            if field == search_string: 
                locid = row[0]
                locname = row[1]
                loccost = row[2]
                locaddress = row[3]
                loccity = row[4]
                locstate = row[5]
                breakflag = True
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51678591

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档