繁体   English   中英

使用Python,如何仅将不同的消息添加到列表?

[英]Using Python, how do I add only distinct messages to a list?

认证的Python Noob。 请多多包涵。

在一百万行(或大约一百万行)文本的多个文件中,我将过滤掉不同的文件。 也就是说,即使那几百万个只包含15条不同的行,代码也应返回15行。

从文件中读取行,如果其中不存在,则将其放在列表中,然后将列表输出到另一个文件。 听起来很简单?

不过有一件小事:

我在寻找消息 ,而不是字符串/子字符串,或者您有什么。 我会在下面解释。

问题:

假设我们在文件中包含以下几行:

  • 随机2345
  • 你好,世界
  • 您的代码是91939
  • 您的代码是54879
  • 您的代码是79865
  • 薄煎饼2451
  • 您的验证码是123456
  • 您的验证码是789101

实际上, if line doesn't exist in myList, add line to myList ,我应该做一个简单的if line doesn't exist in myList, add line to myList ,仍然会返回重复项。 输出应为:

  • 随机2345
  • 你好,世界
  • 您的代码是91939
  • 薄煎饼2451
  • 您的验证码是123456

我要尝试的是:

现在,数字无关紧要,所以我也许可以简单地使用正则表达式或其他方法查找行中的所有数字,将其替换为空,然后将其与列表进行比较(后者也有所有数字都删除了)。

粗略,但这是我能想到的最简单的方法。

还在我这儿?

更多问题:

现在是困难的部分。 除了上面的列表,说我们还有以下内容:

  • 嗨,我叫兰斯 很高兴见到你。
  • 嗨,我叫珍妮。 很高兴见到你。
  • w 名字是约翰·埃里克(John Erik)。 不要碰我的薯条。
  • w 名字是詹姆斯。 不要碰我的薯条。
  • 我喜欢乌龟53669
  • Stefan对您的视频发表了评论。
  • n00bpwn3rz对您的视频发表了评论。
  • RJ想和您谈谈。
  • 珍妮喜欢你的照片。
  • 皮想和你说话
  • 皮说,请访问我的网站www.google.com
  • 约翰·埃里克(John Erik)说,访问我的网站www.johniscool.com
  • 詹姆斯做了果味的冰块。

输出应为以下内容:

  • 嗨,我叫兰斯 很高兴见到你。
  • w 名字是约翰·埃里克(John Erik)。 不要碰我的薯条。
  • 我喜欢乌龟53669
  • Stefan对您的视频发表了评论。
  • RJ想和您谈谈。
  • 珍妮喜欢你的照片。
  • 皮说,请访问我的网站www.google.com
  • 詹姆斯做了果味的冰块。

我的脑袋疼。 我不仅需要将名称作为变量,而且还必须注意网站。

现在,假设我将这条线分解为Chars,将其与列表中的项进行循环比较-也分解为Chars-如果它达到X个正数(line中的Char = list_item中的Char),则不将其添加到名单。 这可行(准确)吗? 如何在代码中做到这一点? 大概是这样吗?

line_char[] = line       #My Name is Jayson
list_char[] = list_item  #My Name is Lance

if (list_char[] contains some sequence of line_char[]):
     #My Name is Jayson = My Name is Lance (12 TRUE [My Name is ], 6 FALSE [Lance/Jayson]; 12 > 6)
     line exists in list
else:
     add line to list

还有其他想法吗? 这可能更多是一个逻辑问题,但是我想在Python中执行此操作,因此我只考虑其优点和局限性。

到目前为止的代码:

伙计们,在这里什么也看不到。

import os

in_path = "../aggregator/"
out_path = "../aggregator_output/"
# For server: for filename in os.listdir(in_path):
# For local: for filename in list_path:
list_path = os.listdir(in_path)
del list_path[0]
for filename in list_path:
    in_base, in_ext = os.path.splitext(filename)
    in_file = os.path.join(in_path, filename)
    out_file = os.path.join(out_path, in_base + "_cleaned.csv")
    print "Processing " + in_file
    print "Writing to " + out_file
    dirty_file = open(in_file, "rb").read().split("\n")
    clean_file = open(out_file "wb")
    list_unique = []
    for line in dirty_file:
        temp_line = re.sub('",', '^', line)
        delimited = temp_line.split(",")
        message = delimited[2]

到目前为止,我所有的代码只不过是过滤文件的右行(第3列)。

我真的很感谢您的帮助,因为这是一个相当有趣的问题,尽管我无法解决自己的问题。

谢谢。

PS-代码循环前注释掉的一部分是考虑到Mac上令人讨厌的.DS存储废话隐藏文件,这会破坏其余代码。 我在Mac上进行测试,并在ubuntu服务器上进行实际操作。

据我所知,当可能的“重复项”不关心数字或名称时,您只想保留第一行。

为什么不 :

  • 查看该行的第一个单词,如果找到新的单词序列,则将其添加到列表中
  • 比较代表两行的两个字符串,并定义一个间隔,从中您知道两行是不同的。

例如,在这两行之间:

  • 嗨,我叫兰斯 很高兴见到你。
  • 嗨,我叫珍妮。 很高兴见到你。

唯一的区别是Lance vs Jenny。

然后,您可以根据该行所有字符的ASCII码总和之差,编写一个比较函数(因为它在Python中不存在)。 并说:如果“散列”接近,则两行相似。

这是用于计算行的哈希值的代码示例:

class myString(str):
  def __hash__(self):
    count = 0
    for c in self:
      count += ord(c)
    return count

a = myString('Hi, my name is Lance. Pleased to meet you.')
b = myString('Hi, my name is Jenny. Pleased to meet you.')
c = myString("Yo, dawg. Name's John Erik. Don't touch my fries.")

hash(a) = 3624
hash(b) = 3657
hash(c) = 4148

希望对您有所帮助! 请注意,对于具有相同字符序列的句子,此解决方案可能会出现问题,例如:

hash(myString('abc')) = 294
hash(myString('bac')) = 294

由于您正在处理英语句子,所以我想知道是否可以将nltk用于此目的。 它提供了词性(POS)标记器,可用于在句子中查找POS。 那些具有相同标签序列的行可能是 “相似”行(也可以通过比较实际标记来进一步改进)。

我从您的问题中尝试了一些示例句子,看起来值得尝试

import nltk

def pos_tags(text):
    return nltk.pos_tag(nltk.word_tokenize(text))

>>> pos_tags("Hi, my name is Lance. Pleased to meet you.")
[('Hi', 'NNP'),
(',', ','),
('my', 'PRP$'),
('name', 'NN'),
('is', 'VBZ'),
('Lance.', 'NNP'),
('Pleased', 'NNP'),
('to', 'TO'),
('meet', 'VB'),
('you', 'PRP'),
('.', '.')]

>>> pos_tags("Hi, my name is Jenny. Pleased to meet you")
[('Hi', 'NNP'),
(',', ','),
('my', 'PRP$'),
('name', 'NN'),
('is', 'VBZ'),
('Jenny.', 'NNP'),
('Pleased', 'NNP'),
('to', 'TO'),
('meet', 'VB'),
('you', 'PRP'),
('.', '.')]

然后可以将每个POS标签标记为字符串并进行比较。 如果它们相同,则很有可能这些线相似并且可以组合在一起。

>>> '-'.join([t[1] for t in pos_tags("Hi, my name is Jenny. Pleased to meet you")])
'NNP-,-PRP$-NN-VBZ-NNP-NNP-TO-VB-PRP-.'

>>> '-'.join([t[1] for t in pos_tags("Hi, my name is Lance. Pleased to meet you")])
'NNP-,-PRP$-NN-VBZ-NNP-NNP-TO-VB-PRP-.'

但是,我不确定它将如何处理一百万行文本。

这种方法使用一个集合,并将其与所有已知集合进行比较。 如果一半的单词在给定的集合中,则假定它们相同且被跳过。

当句子相似时,您必须给出明确的定义,这样才能起作用。

a = """Hi, my name is Lance. Pleased to meet you.
Hi, my name is Jenny. Pleased to meet you.
Yo, dawg. Name's John Erik. Don't touch my fries.
Yo, dawg. Name's James. Don't touch my fries.
I like turtles 53669
Stefan commented on your video.
n00bpwn3rz commented on your video.
RJ wants to talk to you.
Jenny liked your photo.
Pi wants to talk to you.
Pi says visit my website at www.google.com
John Erik says visit my website at www.johniscool.com
James made fruity ice cubes."""


dirty_list = a.split('\n')
clean_list = [] # list of sets containing 'unique sets'
clean_list_pure = [] # list of the original sentences stored as sets in clean_list eg the output
for line in dirty_list:
    line_set = set(line.strip().split(' '))
    if all(len(line_set.intersection(clean_set)) < len(line_set)/2 for clean_set in clean_list):
        clean_list.append(line_set)
        clean_list_pure.append(line.strip())

for cl in clean_list_pure:
    print cl

作为输出,我们得到:

嗨,我叫兰斯 很高兴见到你。

w 名字是约翰·埃里克(John Erik)。 不要碰我的薯条。

我喜欢乌龟53669

Stefan对您的视频发表了评论。

珍妮喜欢你的照片。

皮说,请访问我的网站www.google.com

詹姆斯做了果味的冰块。

暂无
暂无

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

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