列表串联,将以“:”结尾的元素添加到列表中,将其他元素添加到子列表中
List Concatenation, Adding elements that finish with ':' to a list, and others to a sublist
我需要格式化列表的输出,以便将所有以 :
结尾的元素作为第一个元素,而其余元素位于该列表的子列表中。
例如:
假设我们有:
A: B, C
B: D, F | G
到目前为止,我所做的是将其转换为以下列表:
['A:', 'B,', 'C', 'B:', 'D,', ['F', 'G']]
但现在我不知道如何得到以下输出:
[['A:',['B', 'C']], ['B:', ['D', ['F', 'G']]]
你能帮帮我吗?
编辑:
这是我阅读的文件:
file = open('data.txt', 'r')
Y = []
for line in file:
for word in line.strip().split():
Y.append(str(word))
这部分是我将 ors 放入子列表的地方:
text = []
i = 0
while True:
if i > len(Y)-2:
# No more possible |'s, so wrap things up
text.append( Y[-1] )
break
if Y[i+1] == '|':
# Add the items around the |; move past the group:
if Y[i+2].endswith(','):
Y[i+2] = Y[i+2].replace(",", "")
text.append([Y[i], Y[i+2]])
else:
text.append([Y[i], Y[i+2]])
i += 3
else:
# Add the current element & move on
text.append( Y[i] )
i += 1
for id in range(len(text)-1):
if type(text[id]) != str:
if text[id][-1] == text[id+1]:
text.remove(text[id+1])
为什么要先拆分单词并将它们放在列表中?您可以直接遍历您的行并使用一个嵌套列表理解将它们拆分:
import re
with open('data.txt', 'r') as f :
[[k,[p,n.split('|')]] if '|' in n else [k,[p,n]] for k,(p,n) in [[i,j.split(',')] for i,j in [re.split(r'(?<=:) ',line) for line in f]]]
结果:
[['A:', ['B',' C']], ['B:', ['D', [' F ', ' G']]]]
但请注意,这不是通用的解决方案!作为一种更通用的方法,如果您可能有一些其他定界符而不是 |
例如,如果它是一个 none 单词字符,您可以用正则表达式拆分 n
变量(re.split(r'\W',n)
).
注意:r'(?<=:) '
是一个positive look behind,它将根据:
之后的space分割你的行.
如果你不想用 regex
拆分行,你可以使用 str.partition
:
with open('data.txt', 'r') as f :
[[k,[p,n.split('|')]] if '|' in n else [k,[p,n]] for k,(p,n) in [[i+j,t.split(',')] for i,j,t in [line.partition(':') for line in f]]]
[['A:', [' B',' C']], ['B:', [' D', [' F ', ' G']]]]
这看起来像是解析上下文无关语法的家庭作业,|
分隔扩展。所以这里有一些建议:
- 每一行都是一条规则,有左右两边。所以拆分行(您已经一次阅读一行)并分别处理每一行。
- 每行的左侧与扩展部分相隔
:
。在 :
. 拆分
- 右侧可以有多个扩展,由
|
分隔。拆分并处理每一个。
- 一个扩展可以有多个由
,
分隔的标记。在此拆分,丢弃空格,并将它们放入列表中。
请注意,在最后一步之前,您不需要按空格拆分。它使事情变得简单得多。每一步都使用 for 循环(第 2 步除外),他们实际上会自己编写。
编辑: 如果最后一行真的意味着 "D followed by (F or G)",我误解了 |
和 ,
的优先级。把它们按相反的顺序分开。
我需要格式化列表的输出,以便将所有以 :
结尾的元素作为第一个元素,而其余元素位于该列表的子列表中。
例如:
假设我们有:
A: B, C
B: D, F | G
到目前为止,我所做的是将其转换为以下列表:
['A:', 'B,', 'C', 'B:', 'D,', ['F', 'G']]
但现在我不知道如何得到以下输出:
[['A:',['B', 'C']], ['B:', ['D', ['F', 'G']]]
你能帮帮我吗?
编辑: 这是我阅读的文件:
file = open('data.txt', 'r')
Y = []
for line in file:
for word in line.strip().split():
Y.append(str(word))
这部分是我将 ors 放入子列表的地方:
text = []
i = 0
while True:
if i > len(Y)-2:
# No more possible |'s, so wrap things up
text.append( Y[-1] )
break
if Y[i+1] == '|':
# Add the items around the |; move past the group:
if Y[i+2].endswith(','):
Y[i+2] = Y[i+2].replace(",", "")
text.append([Y[i], Y[i+2]])
else:
text.append([Y[i], Y[i+2]])
i += 3
else:
# Add the current element & move on
text.append( Y[i] )
i += 1
for id in range(len(text)-1):
if type(text[id]) != str:
if text[id][-1] == text[id+1]:
text.remove(text[id+1])
为什么要先拆分单词并将它们放在列表中?您可以直接遍历您的行并使用一个嵌套列表理解将它们拆分:
import re
with open('data.txt', 'r') as f :
[[k,[p,n.split('|')]] if '|' in n else [k,[p,n]] for k,(p,n) in [[i,j.split(',')] for i,j in [re.split(r'(?<=:) ',line) for line in f]]]
结果:
[['A:', ['B',' C']], ['B:', ['D', [' F ', ' G']]]]
但请注意,这不是通用的解决方案!作为一种更通用的方法,如果您可能有一些其他定界符而不是 |
例如,如果它是一个 none 单词字符,您可以用正则表达式拆分 n
变量(re.split(r'\W',n)
).
注意:r'(?<=:) '
是一个positive look behind,它将根据:
之后的space分割你的行.
如果你不想用 regex
拆分行,你可以使用 str.partition
:
with open('data.txt', 'r') as f :
[[k,[p,n.split('|')]] if '|' in n else [k,[p,n]] for k,(p,n) in [[i+j,t.split(',')] for i,j,t in [line.partition(':') for line in f]]]
[['A:', [' B',' C']], ['B:', [' D', [' F ', ' G']]]]
这看起来像是解析上下文无关语法的家庭作业,|
分隔扩展。所以这里有一些建议:
- 每一行都是一条规则,有左右两边。所以拆分行(您已经一次阅读一行)并分别处理每一行。
- 每行的左侧与扩展部分相隔
:
。在:
. 拆分
- 右侧可以有多个扩展,由
|
分隔。拆分并处理每一个。 - 一个扩展可以有多个由
,
分隔的标记。在此拆分,丢弃空格,并将它们放入列表中。
请注意,在最后一步之前,您不需要按空格拆分。它使事情变得简单得多。每一步都使用 for 循环(第 2 步除外),他们实际上会自己编写。
编辑: 如果最后一行真的意味着 "D followed by (F or G)",我误解了 |
和 ,
的优先级。把它们按相反的顺序分开。