我在HackerRank上发现了这个问题,我无法理解讨论页面中显示的代码(解决方案)。
问题是:考虑一个列表(list = [])。您可以执行以下命令:
insert i e:在位置插入整数。打印:打印列表。删除e:删除第一次出现的整数。 append e:在列表末尾插入整数。 sort:对列表进行排序。 pop:弹出列表中的最后一个元素。反向:反转列表。
即使我使用if-else解决了问题,我也不明白这段代码是如何工作的:
n = input()
slist = []
for _ in range(n):
s = input().split()
cmd = s[0]
args = s[1:]
if cmd !="print":
cmd += "("+ ",".join(args) +")"
eval("slist."+cmd)
else:
print slist
好吧,代码利用了Python的eval
函数。许多语言都有这个功能:eval
,“evaluate”的缩写,接受一段文本并执行它就像它是程序的一部分,而不仅仅是一个数据输入程序。这一行:
s = input().split()
从用户读取一行输入并将其拆分为基于空格的单词,因此如果键入“insert 1 2”,则s
将设置为列表["insert","1","2"]
。然后通过以下行将其转换为"insert(1,2)"
,然后将其附加到"slist."
并传递给eval
,从而导致执行方法调用slist.insert(1,2)
。所以基本上,这段代码利用了Python已经有方法来执行所需功能的事实,甚至碰巧在问题中使用了相同的名称。它所要做的就是从输入行获取名称和参数,并将它们转换为Python语法。 (print
选项是特殊的,因为没有方法slist.print()
;对于这种情况,它使用全局命令:print slist
。)
在现实世界的代码中,你几乎不应该使用eval
;这是一个非常危险的功能,因为它允许应用程序的用户潜在地使它运行他们想要的任何代码。这肯定是黑客用来闯入事物的更容易的功能之一。
这是肮脏的代码滥用eval
。
基本上,当您输入"remove 1"
时,它会创建一些看起来像sList.remove(1)
的代码,然后将创建的代码提供给eval
。这有Python解释它。
这可能是你在编码比赛之外解决这个问题的最糟糕方式。这里完全不需要使用eval
。
实际上我在代码中发现了一些错误,但我开始理解这段代码是如何运行的。就这个:
输入:
3
1 2 3
cmd = 1 + ( 2 + 3)
然后eval(cmd)
即eval("1 + (2 + 3)")
给出输出6另一个输入:
4
4 5 6 2
cmd = 4 + ( 5 + 6 + 2)
eval(cmd)