我有一个解析语法的python脚本。初始代码是:
num_pro=int(raw_input())
right=[];left=[];
for i in range(num_pro):
map(list.append, (left, right), raw_input().split('->'))
right_edit=[];left_edit=[];i=0
for rhs in right:
parts=rhs.split('|')
for each in parts:
left_edit.append(left[i])
right_edit.append(each)
i+=1
for each in right_edit:
print left_edit[right_edit.index(each)]+" -> "+each
我从包含以下内容的文件中获取输入:
6
E->TZ
Z->+TZ|e
T->FY
Y->*FY|e
F->(E)|a
X->*ZX|e
输出如下:
E -> TZ
Z -> +TZ
Z -> e
T -> FY
Y -> *FY
Z -> e #unexpected
F -> (E)
F -> a
X -> *ZX
Z -> e #unexpected
而预期的输出是:
E -> TZ
Z -> +TZ
Z -> e
T -> FY
Y -> *FY
Y -> e #expected
F -> (E)
F -> a
X -> *ZX
X -> e #expected
我搜索过并发现使用字典不允许使用相同的密钥,并且在集合中也不允许使用相同的值。在我的代码中,我没有使用词典或集合。我也没有使用list.index(value)
。仍然为什么这样的产出即将来临如何获得预期的产出。
答案 0 :(得分:4)
与dict
无关。您的列表实际上包含了预期的内容。
罪魁祸首是输出打印声明:
print left_edit[right_edit.index(each)]+" -> "+each
right_edit.index(each)
会找到第一个元素。由于您有多个e
s,因此始终会找到第一个并将其映射到Z
。
使用类似:
for l, r in zip(left_edit, right_edit):
print l, "->", r
或者:
for i, r in enumerate(right_edit):
print left_edit[i], "->", r
或者甚至更好,寻求更好的数据结构而不是两个不同的列表。我想到了一个简单的单元组两个元组,所以基本上是zip()
在上面的例子中产生的。
答案 1 :(得分:1)
我建议稍微重构一下你的代码。我没有并排使用两个列表,而是建议在列表中使用元组:
而不是
left.append(1)
right.append('a')
你会做的
edit.append((1,'a'))
你的管道参数也一样,它们应该放在第二个元组元素的列表中:
edit.append(('Z', ['+TZ','e']))
代码看起来像这样:
num_pro=int(raw_input())
command=[];
for i in range(num_pro):
command.append(raw_input().split('->')) # command is a list of tuples,
# split by '->'
edit=[];
for cmd in command:
parts = cmd[1].split('|')
edit.append((cmd[0], parts)) # edit is a list of tuples, the first one
# being the keyword before the '->',
# the second one being a list of all
# arguments, split by |
print(edit)
# now printing is simply a matter of two nested fors
for each in edit:
for item in each[1]:
print each[0]+" -> "+item
这显示以下输出:
[('E', ['TZ']), ('Z', ['+TZ', 'e']), ('T', ['FY']),
('Y', ['*FY', 'e']), ('F', ['(E)', 'a']),
('X', ['*ZX', 'e'])]
E -> TZ
Z -> +TZ
Z -> e
T -> FY
Y -> *FY
Y -> e
F -> (E)
F -> a
X -> *ZX
X -> e