我发现了一些python代码来解析linux命令的输出' vmstat'下方。
{{1}}
我想知道是否有人可以向我解释代码在做什么特别是(zip(* map(str.split,sys.stdin)[ - 2:])部分?
谢谢
答案 0 :(得分:1)
这是一些聪明的代码,但有点太聪明了。
让我们分解: dict(zip(* map(str.split,sys.stdin)[ - 2:]))
第一项操作将是: map(str.split,sys.stdin)
Map将给定的函数作为其第一个参数应用于其第二个参数的iterable的每个元素。 (如果第二个参数不是可迭代的,它将被转换为一个以给出可迭代的结果)。 例如,这里:
>>> map (int, ["1", "2", "3"])
[1, 2, 3]
>>> (int, "1")
[1]
所以在这里,第一个表达式可以解读为:“在标准输入上应用str.split”(sys.stdin)。
第一次操作的结果很容易检查:
vmstat | python -c 'import sys; print (map(str.split, sys.stdin))'
[['procs', '-----------memory----------', '---swap--', '-----io----', '-system--', '----cpu----'], ['r', 'b', 'swpd', 'free', 'buff', 'cache', 'si', 'so', 'bi', 'bo', 'in', 'cs', 'us', 'sy', 'id', 'wa'], ['1', '0', '490952', '155924', '437356', '2064528', '0', '0', '3', '59', '0', '1', '6', '1', '91', '2']]
标准输入是3行的数组。每行都使用默认的拆分操作进行拆分,因此可以很好地解析每个元素。现在,我们不需要第一行,所以我们只需要数组的最后两行,因此[-2:]。再一次,这是经典的python:
>>> a = [1,2,3,4]
>>> a[-2:]
[3,4]
所以我们有一个大小为2的列表。第一个列表是带有键的行,第二个列表是带有相应值的行。这看起来像一本字典,不是吗?但它还不是一个。为此我们需要dict。 Dict是一种具有一些构造函数的类型,其中之一是:
help(dict)
[...]
| dict(mapping) -> new dictionary initialized from a mapping object's
| (key, value) pairs
[...]
如果我输入:
dict([('name', 'john'), ('profession', 'computer scientist')])
我明白了:
{'name': 'john', 'profession': 'computer scientist'}
但是我们没有元组列表[(键,值)],我们有一个列表[[key,key,key ...],[value,value,value ...]]。
获取元组列表的一种方法是使用zip函数。
>>> k = ['key1', 'key2', 'key3']
>>> v = ['value1', 'value2', 'value3']
>>> zip(k,v)
[('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3')]
zip的结果是我们可以用来构建一个字典的东西! 但是我们这里没有两个独立的迭代器k和v。我们只有一份清单!所以这里还有另一个技巧:将参数作为列表传递。这在此处记录: https://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists
这个想法是,如果你有一个带x参数的函数,你可以明确地给它们,就像这样:
def fun(a,b):
return a + b
fun(2,3)
但您也可以使用*语法使用列表调用它们,如下所示:
fun(*[2,3])
“*”符号表示:“将列表中的所有内容解压缩到每个参数”。请注意,如果我这样做:
fun(*[2,3,4])
它会失败,就像我尝试过一样:
fun(2,3,4)
因为有趣只需要2个参数。所以在这里,我们的列表[[key,key ...],[value,value]]将被解压缩,所以真正的调用是zip([key,key ...],[value,value .. 。])...它给了我们准确的东西,一本字典。在这本字典中,我们只需使用键“cache”获取值。我们已经完成了。
这个单行是聪明的,但阅读不愉快。 HuStmpHrrr在问题的评论中提供了一种更好的方法。