问题描述
我在 HackerRank 上发现了这个问题,但我无法理解讨论页面中显示的代码(解决方案)。
问题是:考虑一个列表 (list = [])。 您可以执行以下命令:
插入即:在位置插入整数。 打印:打印列表。 remove e:删除第一次出现的 integer 。 append e:在列表末尾插入整数。 sort:对列表进行排序。 pop:从列表中弹出最后一个元素。 reverse:反转列表。
即使我已经使用 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
1楼
这是滥用eval
的脏代码。
基本上,例如,当您输入"remove 1"
,它会创建一些类似于sList.remove(1)
的代码,然后将创建的代码提供给eval
。
这有Python解释它。
不过,这可能是你在编码竞赛之外解决这个问题的最糟糕的方法。
这里完全没有必要使用eval
。
2楼
好吧,代码利用了 Python 的eval
函数。
许多语言都具有此功能: eval
,“评估”的缩写,获取一段文本并执行它,就好像它是程序的一部分,而不仅仅是提供给程序的一段数据。
这一行:
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
;
这是一个非常危险的功能,因为它允许您的应用程序的用户潜在地使其运行他们想要的任何代码。
这当然是黑客用来闯入事物的更简单的功能之一。
3楼
其实我在代码中发现了一些错误,但我对这段代码的运行方式有了了解。 就这个:
输入 :
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)
4楼
if __name__ == '__main__':
N = int(raw_input())
lst=[]
for _ in range(N):
cmd, *line = input().split()
ele= list(map(str,line))
if cmd in dir(lst):
exec('lst.'+cmd+'('+','.join(ele)+')')
elif cmd == 'print':
print(lst)
else:
print('wrong command', cmd)