繁体   English   中英

从字符串列表中删除重复项

[英]removing duplicates from a list of strings

我正在尝试读取文件,制作单词列表,然后制作新单词列表以删除重复项。 我无法将这些单词添加到新列表中。 它说没有类型对象没有属性'append'

这是一些代码:

fh = open("gdgf.txt")
lst = list()

file = fh.read()
for line in fh:
    line = line.rstrip()

file = file.split()
for word in file:
    if word  in lst: 
        continue
    lst = lst.append(word)

print lst

python append将返回None 。因此set将有助于删除重复项。

In [102]: mylist = ["aa","bb","cc","aa"]

In [103]: list(set(mylist))
Out[103]: ['aa', 'cc', 'bb']

希望这可以帮助

就你而言

file = fh.read()

在此之后fh将是一个空的生成器。因此您不能使用它,因为它已经被使用了。您必须对变量file进行操作

append在原处追加一个项目,这意味着它不返回任何值。 附加word时,您应该摆脱lst=

if word in lst:
    continue
lst.append(word)

您将用append函数(不是列表)的返回值替换列表。 只需这样做:

lst.append(word)

list.append()是就地追加,它返回None (因为它不返回任何内容)。 因此您无需将list.append()的返回值设置回列表。 只需将lst=lst.append(word)更改为-

lst.append(word)

另一个问题是,您首先在文件上调用.read() ,然后遍历其行,则无需这样做。 只需删除迭代部分。


另外,如果您对元素的顺序不感兴趣,则删除重复项的简单方法是使用set。

范例-

>>> lst = [1,2,3,4,1,1,2,3]
>>> set(lst)
{1, 2, 3, 4}

因此,您可以将lst初始化为lst=set() 然后使用lst.add()元素,您甚至不需要检查该元素是否已经存在。 最后,如果您确实希望将结果作为列表,请执行list(lst) ,将其转换为列表。 (尽管这样做时,您要考虑将变量重命名为更好的名称,以便于理解变量set而不是list

append修改它被调用的列表,并返回None 即,您应该替换以下行:

lst=lst.append(word)

简单地

lst.append(word)
fh=open("gdgf.txt")

file=fh.read()
for line in fh:
    line=line.rstrip()
lst = []
file=file.split()
for word in file:
    lst.append(word)
print (set(lst))

append()不返回任何内容,因此请不要分配它。 lst.append()就足够了。

修改后的代码:

fh = open("gdgf.txt")
lst = []

file=fh.read()
for line in fh:
     line = line.rstrip()

file=file.split()

for word in file:
     if word  in lst: 
         continue
     lst.append(word)

print lst

我建议您使用set() ,因为它用于唯一元素的无序集合

fh = open("gdgf.txt")
lst = []

file = fh.read()
for line in fh:
     line = line.rstrip()

file = file.split()

lst = list( set(lst) )

print lst

您可以通过将单词直接添加到集合中来简化代码。 集合不允许重复,因此您将只剩下唯一的单词:

words = set()

with open('gdgf.txt') as f:
   for line in f:
      for word in line.strip():
          words.add(word.strip())

print(words)

上述逻辑的问题在于,以标点符号结尾的单词将被计为单独的单词:

>>> s = "Hello? Hello should only be twice in the list"
>>> set(s.split())
set(['be', 'twice', 'list', 'should', 'Hello?', 'only', 'in', 'the', 'Hello'])

你可以看到你Hello? Hello

您可以使用正则表达式提取单词来增强上面的代码,这将解决标点符号的问题:

>>> set(re.findall(r"(\w[\w']*\w|\w)", s))
set(['be', 'list', 'should', 'twice', 'only', 'in', 'the', 'Hello'])

现在您的代码是:

import re

with open('gdgf.txt') as f:
   words = set(re.findall(r"(\w[\w']*\w|\w)", f.read(), re.M))

print(words)

即使使用上述方法,您仍将有重复项,因为Wordword将被计数两次。 如果要存储每个单词的单个版本,则可以进一步增强它。

我认为这个问题的解决方案可以更简洁:

 import string with open("gdgf.txt") as fh: word_set = set() for line in fh: line = line.split() for word in line: # For each character in string.punctuation, iterate and remove # from the word by replacing with '', an empty string for char in string.punctuation: word = word.replace(char, '') # Add the word to the set word_set.add(word) word_list = list(word_set) # Sort the set to be fastidious. word_list.sort() print(word_list) 

关于通过“分割”计数单词的一件事是您正在空格上分割,因此这将使“单词”成为"Hello!"类的东西"Hello!" "Really?" 这些单词将包含标点符号,可能不是您想要的。

您的变量名可能更具描述性,缩进似乎有些偏离,但我认为这可能是删减/粘贴到发布中的问题。 我试图根据与之交互的任何逻辑结构(文件,行,字,字符等)来命名我使用的变量。

要查看“ string.punctuation”的内容,您可以启动iPython,导入string,然后只需输入string.punctuation即可查看内容。

还不清楚是否需要列表,或者是否只需要包含唯一单词列表的数据结构。 为了避免重复,已经正确创建的集合或列表应该可以解决问题。 接下来的问题,我使用了一个set来唯一存储元素,然后将该set简单地转换为list ,然后按字母顺序对其进行排序。

希望这可以帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM