查找已连接的令牌
Find tokens that are connected
我编写了获取文本标记作为输入的代码:
tokens = ["Tap-", "Berlin", "Was-ISt", "das", "-ist", "cool", "oh", "Man", "-Hum", "-Zuh-UH-", "glit"]
代码应该找到所有包含连字符或用连字符相互连接的标记:基本上输出应该是:
[["Tap-", "Berlin"], ["Was-ISt"], ["das", "-ist"], ["Man", "-Hum", "-Zuh-UH-", "glit"]]
我写了一个代码,但不知何故我没有得到带有连字符的令牌:尝试一下:http://goo.gl/iqov0q
def find_hyphens(self):
tokens_with_hypens =[]
for i in range(len(self.tokens)):
hyp_leng = 0
while self.hypen_between_two_tokens(i + hyp_leng):
hyp_leng += 1
if self.has_hypen_in_middle(i) or hyp_leng > 0:
if hyp_leng == 0:
tokens_with_hypens.append(self.tokens[i:i + 1])
else:
tokens_with_hypens.append(self.tokens[i:i + hyp_leng])
i += hyp_leng - 1
return tokens_with_hypens
我做错了什么?有没有更高效的解决方案?谢谢
我在你的代码中发现了 3 个错误:
1) 您在这里比较的是 tok1
的最后两个字符,而不是 tok1
的最后一个字符和 tok2
的第一个字符:
if "-" in joined[len(tok1) - 2: len(tok1)]:
# instead, do this:
if "-" in joined[len(tok1) - 1: len(tok1) + 1]:
2) 您在这里省略了最后一个匹配的标记。将此处切片的结束索引增加 1:
tokens_with_hypens.append(self.tokens[i:i + hyp_leng])
# instead, do this:
tokens_with_hypens.append(self.tokens[i:i + 1 + hyp_leng])
3) 您不能在 python 中操作 for i in range
循环的索引。下一次迭代将只检索下一个索引,覆盖您的更改。相反,您可以像这样使用 while 循环:
i = 0
while i < len(self.tokens):
[...]
i += 1
这 3 次更正使您通过了测试:http://goo.gl/fd07oL
尽管如此,我还是忍不住从头开始写一个算法,尽可能简单地解决你的问题:
def get_hyphen_groups(tokens):
i_start, i_end = 0, 1
while i_start < len(tokens):
while (i_end < len(tokens) and
(tokens[i_end].startswith("-") ^ tokens[i_end - 1].endswith("-"))):
i_end += 1
yield tokens[i_start:i_end]
i_start, i_end = i_end, i_end + 1
tokens = ["Tap-", "Berlin", "Was-ISt", "das", "-ist", "cool", "oh", "Man", "-Hum", "-Zuh-UH-", "glit"]
for group in get_hyphen_groups(tokens):
print ("".join(group))
要排除 1 元素组,就像在您的预期结果中一样,将 yield
包装到此 if
:
if i_end - i_start > 1:
yield tokens[i_start:i_end]
要包含已包含连字符的 1 元素组,请将 if
更改为例如:
if i_end - i_start > 1 or "-" in tokens[i_start]:
yield tokens[i_start:i_end]
您的方法有一个问题是试图在 for i in range(len(self.tokens))
循环中更改 i
的值。它不会起作用,因为 i
的值将在每次迭代中从 range
获取下一个值,而忽略您的更改。
我将您的算法更改为使用迭代算法,该算法一次从列表中弹出一个项目并决定如何处理它。它使用一个缓冲区来存储属于一个链的项目,直到它完成。
完整代码为:
class Hyper:
def __init__(self, tokens):
self.tokens = tokens
def find_hyphens(self):
tokens_with_hypens =[]
copy = list(self.tokens)
buffer = []
while len(copy) > 0:
item = copy.pop(0)
if self.has_hyphen_in_middle(item) and item[0] != '-' and item[-1] != '-':
# words with hyphens that are not part of a bigger chain
tokens_with_hypens.append([item])
elif item[-1] == '-' or (len(copy) > 0 and copy[0][0] == '-'):
# part of a chain - append to the buffer
buffer.append(item)
elif len(buffer) > 0:
# the last word in a chain - the buffer contains the complete chain
buffer.append(item)
tokens_with_hypens.append(buffer)
buffer = []
return tokens_with_hypens
@staticmethod
def has_hyphen_in_middle(input):
return len(input) > 2 and "-" in input[1:-2]
tokens = ["Tap-", "Berlin", "Was-ISt", "das", "-ist", "cool", "oh", "Man", "-Hum", "-Zuh-UH-", "glit"]
hyper = Hyper(tokens)
result = hyper.find_hyphens()
print(result)
print(result == [["Tap-", "Berlin"], ["Was-ISt"], ["das", "-ist"], ["Man", "-Hum", "-Zuh-UH-", "glit"]])
我编写了获取文本标记作为输入的代码:
tokens = ["Tap-", "Berlin", "Was-ISt", "das", "-ist", "cool", "oh", "Man", "-Hum", "-Zuh-UH-", "glit"]
代码应该找到所有包含连字符或用连字符相互连接的标记:基本上输出应该是:
[["Tap-", "Berlin"], ["Was-ISt"], ["das", "-ist"], ["Man", "-Hum", "-Zuh-UH-", "glit"]]
我写了一个代码,但不知何故我没有得到带有连字符的令牌:尝试一下:http://goo.gl/iqov0q
def find_hyphens(self):
tokens_with_hypens =[]
for i in range(len(self.tokens)):
hyp_leng = 0
while self.hypen_between_two_tokens(i + hyp_leng):
hyp_leng += 1
if self.has_hypen_in_middle(i) or hyp_leng > 0:
if hyp_leng == 0:
tokens_with_hypens.append(self.tokens[i:i + 1])
else:
tokens_with_hypens.append(self.tokens[i:i + hyp_leng])
i += hyp_leng - 1
return tokens_with_hypens
我做错了什么?有没有更高效的解决方案?谢谢
我在你的代码中发现了 3 个错误:
1) 您在这里比较的是 tok1
的最后两个字符,而不是 tok1
的最后一个字符和 tok2
的第一个字符:
if "-" in joined[len(tok1) - 2: len(tok1)]:
# instead, do this:
if "-" in joined[len(tok1) - 1: len(tok1) + 1]:
2) 您在这里省略了最后一个匹配的标记。将此处切片的结束索引增加 1:
tokens_with_hypens.append(self.tokens[i:i + hyp_leng])
# instead, do this:
tokens_with_hypens.append(self.tokens[i:i + 1 + hyp_leng])
3) 您不能在 python 中操作 for i in range
循环的索引。下一次迭代将只检索下一个索引,覆盖您的更改。相反,您可以像这样使用 while 循环:
i = 0
while i < len(self.tokens):
[...]
i += 1
这 3 次更正使您通过了测试:http://goo.gl/fd07oL
尽管如此,我还是忍不住从头开始写一个算法,尽可能简单地解决你的问题:
def get_hyphen_groups(tokens):
i_start, i_end = 0, 1
while i_start < len(tokens):
while (i_end < len(tokens) and
(tokens[i_end].startswith("-") ^ tokens[i_end - 1].endswith("-"))):
i_end += 1
yield tokens[i_start:i_end]
i_start, i_end = i_end, i_end + 1
tokens = ["Tap-", "Berlin", "Was-ISt", "das", "-ist", "cool", "oh", "Man", "-Hum", "-Zuh-UH-", "glit"]
for group in get_hyphen_groups(tokens):
print ("".join(group))
要排除 1 元素组,就像在您的预期结果中一样,将 yield
包装到此 if
:
if i_end - i_start > 1:
yield tokens[i_start:i_end]
要包含已包含连字符的 1 元素组,请将 if
更改为例如:
if i_end - i_start > 1 or "-" in tokens[i_start]:
yield tokens[i_start:i_end]
您的方法有一个问题是试图在 for i in range(len(self.tokens))
循环中更改 i
的值。它不会起作用,因为 i
的值将在每次迭代中从 range
获取下一个值,而忽略您的更改。
我将您的算法更改为使用迭代算法,该算法一次从列表中弹出一个项目并决定如何处理它。它使用一个缓冲区来存储属于一个链的项目,直到它完成。
完整代码为:
class Hyper:
def __init__(self, tokens):
self.tokens = tokens
def find_hyphens(self):
tokens_with_hypens =[]
copy = list(self.tokens)
buffer = []
while len(copy) > 0:
item = copy.pop(0)
if self.has_hyphen_in_middle(item) and item[0] != '-' and item[-1] != '-':
# words with hyphens that are not part of a bigger chain
tokens_with_hypens.append([item])
elif item[-1] == '-' or (len(copy) > 0 and copy[0][0] == '-'):
# part of a chain - append to the buffer
buffer.append(item)
elif len(buffer) > 0:
# the last word in a chain - the buffer contains the complete chain
buffer.append(item)
tokens_with_hypens.append(buffer)
buffer = []
return tokens_with_hypens
@staticmethod
def has_hyphen_in_middle(input):
return len(input) > 2 and "-" in input[1:-2]
tokens = ["Tap-", "Berlin", "Was-ISt", "das", "-ist", "cool", "oh", "Man", "-Hum", "-Zuh-UH-", "glit"]
hyper = Hyper(tokens)
result = hyper.find_hyphens()
print(result)
print(result == [["Tap-", "Berlin"], ["Was-ISt"], ["das", "-ist"], ["Man", "-Hum", "-Zuh-UH-", "glit"]])