【问题标题】:matching python nested lists with (random variables)将python嵌套列表与(随机变量)匹配
【发布时间】:2016-09-12 10:45:22
【问题描述】:

我在字符串之间做一些匹配。

t1 = '[go:VB, [like:IN, [i:PR]], [to:TO], [there:RB]]'
t2 = '[A, [like:IN, [B]], [to:TO], [C]]'

t1 和 t2 的形状都是 X:Y

我称之为

X : 单词

Y : 标签

我愿意

t1 == t2

在这个例子中,如果我们说这样的话,这是可以做到的:

for i in t1: 
    if i.tag in (‘NN’, ‘RB’, ‘JJ’,’ VB’, PN’):
        X:Y = #ANY ONE UPPER CASE VARIABLE

不能这样做,因为它们不是列表,我不能这样做 (eval) 因为 (: ),列表中不接受

我所做的就是我分裂 (‘ , ‘)

t1 = t1.split(',')
t2 = t2.split(',')

现在的新列表类似于:

t1 = ['[go:VB', ' [like:IN', ' [i:PR]]', ' [to:TO]', ' [there:RB]]']
t2 = ['[A', ' [like:IN', ' [B]]', ' [to:TO]', ' [C]]']

现在

t1[0] == t2[0]   #return FALSE
t1[1] == t2[1]   #return TRUE
t1[2] == t2[2]   #return FALSE
t1[3] == t2[3]   #return TRUE
t1[4] == t2[4]   #return FALSE

我需要它们都返回 TRUE,即使我将变量从 (A) 更改为任何一个大写字母(例如 Z、H、X)

我想把最后一个成员放在最后一个成员之前,然后只选择标签

>>> t1[0]
'[go:VB'
# to select only the tag
>>> t1[0][-2:]
'VB' # << This is what I want

>>> t1[1]
' [like:IN'
# to select only the tag
>>> t1[1][-2:]
'IN'  # << This is what I want

>>> t1[2]
' [i:PR]]'
# to select only the tag 
>>> t1[1][-2:]
']]'   # << This is NOT what I want

我不知道在这里做什么,但可能有一个有用的东西可以使用,但我不知道如何在这里适应它

>>> t1[0][-2:].isalpha()
True
>>> t1[1][-2:].isalpha()
True
>>> t1[2][-2:].isalpha()
False

【问题讨论】:

  • 听起来您的输入数据格式非常烦人。您是否创建/维护了生成初始 t1t2 的函数?如果是这样,则应在尝试此问题之前先解决此问题。
  • t2 是从其他人那里导入的。 t1 差不多是这样,但它曾经有元组,我删除了它们。

标签: python list python-2.7 pattern-matching match


【解决方案1】:

这里是您的格式问题的快速修复 -

import itertools
t1 = '[go:VB, [like:IN, [i:PR]], [to:TO], [there:RB]]'
t2 = '[A, [like:IN, [B]], [to:TO], [C]]'
t1=t1.replace("]","")
t1=t1.replace("[","")
t2=t2.replace("[","")
t2=t2.replace("]","")
t1=t1.split(",")
t2=t2.split(",")
print(t1)
print(t2)
for i,j in itertools.zip_longest(t1,t2):
    if i[-2:]==j[-2:]:
        print("true")
    else:
        print("false")

输出是 -

['go:VB', ' like:IN', ' i:PR', ' to:TO', ' there:RB']
['A', ' like:IN', ' B', ' to:TO', ' C']
false
true
false
true
false

但是,我不喜欢这种方法,我会解释原因。从您的部分代码中,我可以理解您正在使用句子和词性标记(POS)。我将通过帮助您生成一个实际可读的 POS 列表来解决您的问题。我在 python 中使用 NLTK 模块,这是一个强大的自然语言处理工具(经过结构化数据训练) 你可以找到文档here

import nltk
import itertools
from nltk import tokenize
from nltk.tokenize import *
text1= word_tokenize("And now for something completely different")
text2= word_tokenize("And won for something completely same")
t1=nltk.pos_tag(text1)
t2=nltk.pos_tag(text2)
print(t1)
print(t2)

for i ,j in itertools.zip_longest( t1,t2 ):
    if i[1]==j[1]:
        print("true")
    else:
        print("false")

这就是输出。

[('And', 'CC'), ('now', 'RB'), ('for', 'IN'), ('something', 'NN'), ('completely', 'RB'), ('different', 'JJ')]
[('And', 'CC'), ('won', 'VBD'), ('for', 'IN'), ('something', 'NN'), ('completely', 'RB'), ('same', 'JJ')]
true
false
true
true
true
true

密切注意输出,最后一个true的原因是它们都是形容词。让我尽可能简单地解释代码。现在你可以看到,word_tokenize()是一个分解将句子放入其各自的标记中(尝试使用诸如“不能”之类的词,看看会发生什么),pos_tag() 执行 POS 标记。我相信您知道这一点。注意 - 这里,“:”默认替换为“,”。从而更容易区分单词和标签。这个模块不仅可以帮助您在此格式化它非常强大。您可以训练您的数据,提取实体并大大提高您的工作质量。

但是,注意到您的句子中存在变量(我想知道它们来自哪里),我建议迭代列表中的每个项目并跳过变量(因为您希望它们给出 TRUE 输出反正)。然后,只需比较 T1 和 T2 之间单词的标签。

【讨论】:

  • 好吧,既然您已经编辑了它,您似乎只需要标签。那么最简单的方法就是只取 t1 和 t2 并删除重复出现的 [ 和 ] 括号。使用 split(",") 只会让你的格式变得更糟。因此,删除括号并执行与您在编辑中使用的相同的索引搜索。它应该可以工作。
  • 我这样做并编辑了我的答案。告诉我它是否适合你。 :)
  • 所以我阅读了您的其他帖子,它解释了如何以不同方式获取 t1 和 t2。老实说,我觉得这是你坚持使用 NLTK 的更多理由。删除元组、创建不必要的列表或获取格式错误的数据时,您将不会那么头疼。但是请记住,NLTK 适用于结构化数据。如果您在使用 NLTK 时遇到问题,请提出更多问题或尝试使用 spaCy API 或 Alchemy API。同样,这些对于您的需求来说可能过于强大,但它们可以为您省去很多麻烦。
  • 你说得对,我在句子中的每个单词都使用了 POS。但实际上 t1t2 是解析树,所以我根本无法删除 ' [ ' 和 ' ] ',所以我不是在寻找扁平化列表。
  • 非常感谢您的帮助,这次讨论非常有用。非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-09
  • 2021-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多