【问题标题】:Python3: Autcomplete text using CSVPython3:使用 CSV 自动完成文本
【发布时间】:2018-01-21 05:11:45
【问题描述】:

我想做的是一个自动完成脚本,它使用一个 csv 文件,您可以从用户输入中获得最有可能的建议,使用 csv 的第二行(它说明给定单词的出现次数)确定可能性。

到目前为止,我已经在导入 CSV 后测试了两种方法,第一种是将其放入排序列表(最高数字优先)。然后我将循环并输出第一个遇到的以用户输入开头的单词。然而,这个想法从根本上存在缺陷,因为我找不到根据数字的实际值对列表进行排序的解决方案,只有开始的数字。例如。数字九 (9) 的排名高于 7184。

thelist = open('alphabetical.csv', 'r')
csv1 = csv.reader(thelist, delimiter = ',')
sortedlist = sorted(csv1, key = lambda x: x[1], reverse=True)

一个 sn-p 可能看起来像: [['with', '1671'], ['seldom', '2'], ['green', '246']] - 等等。

这是函数当前的样子:

def main():
"""Initialize main loop."""
word = ""

while word != "q":
    word = input("Type word: ").lower()
    print("Autocompletion finished: ", autocomplete())

def autocomplete():
"""Return autocomplete suggestions."""
filtered_words = filter(lambda x: x.startswith(word), sortedlist)
return filtered_words

输入后的结果是:

<filter object at 0x7fbfb27ca860>

我知道代码有缺陷,而且还有更多问题,所以输出不是它所需要的对我来说并不奇怪。

从当前函数获得给定输出后,我担心无法使用列表,因此我目前正在尝试使用字典,但我最不想做的就是在实际上一开始就在正确的轨道上。因此,我向您寻求有关如何解决此问题的任何可能的指导和建议。

谢谢。

【问题讨论】:

  • python 3过滤器需求列表:filtered_words = list(filter(lambda x: x[1].startswith(word), sortedlist))
  • 另外,你的排序方式很麻烦。并且转向列表将不起作用,因为您放置了 csv 文件的行,而不是字符串。
  • 另外,我不确定您的自动完成词典的大小是多少,但我建议您将完成词典表示为 Multiway Trie,您可以在其上执行 BFS/DFS 而不是使用排序的列表
  • @NiemaMoshiri 我很感兴趣,不知道这种方法,因为我完全是编程初学者。我会对此进行更多研究,谢谢!

标签: python python-3.x csv autocomplete


【解决方案1】:

首先,为什么要排序然后创建一个新列表?

sort = sorted(csv1, key = lambda x: x[1])
for row in sort:
    sortedlist.append(row)

可能

sortedlist = sorted(csv1, key = lambda x: x[1])

您的其他错误:filter 在 python 3 中不再返回列表,它是懒惰地评估。您必须强制对其进行列表迭代。

如果您这样做,您会意识到还有另一个错误,因为startswith 适用于 ,而不适用于字符串。

所以快速修复将是:

filtered_words = list(filter(lambda x: x[0].startswith(word), sortedlist))

这将返回行,而不是单词,顺便说一句。

但是使用list + filter + lambda 变得繁琐且性能不佳。更喜欢简单的列表理解:

filtered_words = [x for x in sortedlist if x[0].startswith(word)]

也返回行。要仅获取可以对两个字段使用解包并丢弃数字的单词

filtered_words = [x for x,_ in sortedlist if x.startswith(word)]

或者您可以从一开始就丢弃这些数字:

sortedlist = [x[0] for x in sorted(csv1, key = lambda x: x[1])]

这会让你改变过滤器:

filtered_words = [x for x in sortedlist if x.startswith(word)]

这种方法很简单,但正如 cmets 中所述,它不是最有效的,因为它意味着线性搜索(并且没有利用列表已排序的事实)

【讨论】:

  • 感谢您的回复,繁琐的排序列表确实是调试出来的,我应该按照建议的方式发布它,但是结果是一样的,例如。未按预期排序。我将研究您对列表理解的建议,看看是否能找到解决方案,非常感谢!
猜你喜欢
  • 2014-01-04
  • 1970-01-01
  • 1970-01-01
  • 2017-08-23
  • 2019-08-06
  • 2018-04-03
  • 2011-12-13
  • 2017-05-25
  • 2019-11-08
相关资源
最近更新 更多