簡體   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