Python: 如何根据条件获取列表列表的下一个序列?
Python: how to get the next sequence of a list of lists based on a condition?
我使用了一个 NLP 分块器,它错误地将术语 'C++' 和 'C#' 拆分为:C (NN), +(SYM), +(SYM), C (NN), #( SYM).
不正确分块的结果列表如下所示:
l = [['C', 'NN'], ['+', 'SYM'], ['+', 'SYM'], ['C', 'NN'], ['#', 'NN']]
我想 post 处理这个列表,方法是识别每个列表的索引 0 中的字符串 'C' 和下一行 '+'、'+' 或 ' #'。然后我想连接这些字符串,这样 'C','+','+' 只需将它们加在一起就变成 'C++' 。这必须是通用的,因此它应该适用于包含多个不同单词的列表,但仍然连接所需的字符串。
期望的结果:
l_desired = [['C++', 'NN'], ['C#', 'NN']]
我可以独立识别列表中的项目(索引 0),但我不知道如何识别所需的顺序。我的想法是使用 next()
函数,虽然我不知道从哪里开始。
基本上,我只是一个一个地附加每个字母。
当与我们要查找的两个字符串(“C++”或“C#”)匹配时,它会将该值添加到列表中并重置字符串。
l = [['C', 'NN'], ['+', 'SYM'], ['+', 'SYM'], ['C', 'NN'], ['#', 'NN']]
l_desired = []
x, y = "", ""
for item in l:
if x == "":
y = item[1]
x += item[0]
if x in ["C++", "C#"]:
l_desired.append([x, y])
x, y = "", ""
print("RESULT: " + l_desired)
# RESULT: [['C++', 'NN'], ['C#', 'NN']]
您可以遍历列表并检查第一个元素是否为字母,在这种情况下作为新项追加,否则更新最后一项:
from string import ascii_letters
letters = set(ascii_letters)
out = []
for e in l:
if e[0][0] in letters:
out.append(e.copy()) # making a copy not to affect original list
elif out: # this is to check that out is not empty (edge case)
out[-1][0] += e[0]
或者使用符号黑名单:
symbols = set('+#')
out = []
for e in l:
if e[0] in symbols and out:
out[-1][0] += e[0]
else:
out.append(e.copy())
输出:
[['C++', 'NN'], ['C#', 'NN']]
这是生成器的简单实现,它将读取原始列表作为迭代器并“标记化”它(再次 - 简单地):
def the_generator(l):
it = iter(l)
def get_tok():
x = it.next()
return (",".join(x),x)
while True:
tok1 = get_tok()
tok3 = None
if tok1[0] != 'C,NN':
yield tok1[1]
continue
tok2 = get_tok()
if tok2[0] == '#,NN':
yield ['C#','NN']
continue
if tok2[0] == '+,SYM':
tok3 = get_tok()
if tok3[0] == '+,SYM':
yield ['C++','NN']
continue
yield tok1[1]
yield tok2[1]
if tok3:
yield tok3[1]
l = [['Dog', 'NN'], ['C', 'NN'], ['+', 'SYM'], ['+', 'SYM'], ['C', 'NN'], ['#', 'NN'], ['C', 'NN'], ['+','SYM'], ['#', 'NN']]
for x in the_generator(l):
print(x)
输出:
['Dog', 'NN']
['C++', 'NN']
['C#', 'NN']
['C', 'NN']
['+', 'SYM']
['#', 'NN']
生成器不会一次转换所有列表,仅在需要时转换。要一次创建一个新列表,您可以执行 list(the_generator(l))
.
我正在用 join()
对各个标记进行字符串化以简化比较。当原始迭代结束并且 .next()
引发 StopIteration
.
时,while True
循环自然结束
我使用了一个 NLP 分块器,它错误地将术语 'C++' 和 'C#' 拆分为:C (NN), +(SYM), +(SYM), C (NN), #( SYM).
不正确分块的结果列表如下所示:
l = [['C', 'NN'], ['+', 'SYM'], ['+', 'SYM'], ['C', 'NN'], ['#', 'NN']]
我想 post 处理这个列表,方法是识别每个列表的索引 0 中的字符串 'C' 和下一行 '+'、'+' 或 ' #'。然后我想连接这些字符串,这样 'C','+','+' 只需将它们加在一起就变成 'C++' 。这必须是通用的,因此它应该适用于包含多个不同单词的列表,但仍然连接所需的字符串。
期望的结果:
l_desired = [['C++', 'NN'], ['C#', 'NN']]
我可以独立识别列表中的项目(索引 0),但我不知道如何识别所需的顺序。我的想法是使用 next()
函数,虽然我不知道从哪里开始。
基本上,我只是一个一个地附加每个字母。
当与我们要查找的两个字符串(“C++”或“C#”)匹配时,它会将该值添加到列表中并重置字符串。
l = [['C', 'NN'], ['+', 'SYM'], ['+', 'SYM'], ['C', 'NN'], ['#', 'NN']]
l_desired = []
x, y = "", ""
for item in l:
if x == "":
y = item[1]
x += item[0]
if x in ["C++", "C#"]:
l_desired.append([x, y])
x, y = "", ""
print("RESULT: " + l_desired)
# RESULT: [['C++', 'NN'], ['C#', 'NN']]
您可以遍历列表并检查第一个元素是否为字母,在这种情况下作为新项追加,否则更新最后一项:
from string import ascii_letters
letters = set(ascii_letters)
out = []
for e in l:
if e[0][0] in letters:
out.append(e.copy()) # making a copy not to affect original list
elif out: # this is to check that out is not empty (edge case)
out[-1][0] += e[0]
或者使用符号黑名单:
symbols = set('+#')
out = []
for e in l:
if e[0] in symbols and out:
out[-1][0] += e[0]
else:
out.append(e.copy())
输出:
[['C++', 'NN'], ['C#', 'NN']]
这是生成器的简单实现,它将读取原始列表作为迭代器并“标记化”它(再次 - 简单地):
def the_generator(l):
it = iter(l)
def get_tok():
x = it.next()
return (",".join(x),x)
while True:
tok1 = get_tok()
tok3 = None
if tok1[0] != 'C,NN':
yield tok1[1]
continue
tok2 = get_tok()
if tok2[0] == '#,NN':
yield ['C#','NN']
continue
if tok2[0] == '+,SYM':
tok3 = get_tok()
if tok3[0] == '+,SYM':
yield ['C++','NN']
continue
yield tok1[1]
yield tok2[1]
if tok3:
yield tok3[1]
l = [['Dog', 'NN'], ['C', 'NN'], ['+', 'SYM'], ['+', 'SYM'], ['C', 'NN'], ['#', 'NN'], ['C', 'NN'], ['+','SYM'], ['#', 'NN']]
for x in the_generator(l):
print(x)
输出:
['Dog', 'NN']
['C++', 'NN']
['C#', 'NN']
['C', 'NN']
['+', 'SYM']
['#', 'NN']
生成器不会一次转换所有列表,仅在需要时转换。要一次创建一个新列表,您可以执行 list(the_generator(l))
.
我正在用 join()
对各个标记进行字符串化以简化比较。当原始迭代结束并且 .next()
引发 StopIteration
.
while True
循环自然结束