我在下面找到了一些python代码来解析linux命令'vmstat‘的输出。
vmstat | python -c 'import sys; print dict(zip(*map(str.split, sys.stdin)[-2:])).get("cache")'
vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
11 0 385372 101696 61704 650716 0 1 5 9 6 12 5 2 92 0我想知道是否有人可以向我解释一下代码是做什么的,特别是(zip(*map(str.split,sys.stdin)-2:)部分?
谢谢
发布于 2015-05-25 22:19:19
这是一些聪明的代码,但有点太聪明了。
让我们分解一下: dict(zip(*map(str.split,sys.stdin)-2:))
第一个操作是: map(str.split,sys.stdin)
Map将作为其第一个参数给出的函数应用于其第二个参数的可迭代元素的每个元素。(如果第二个参数不是可迭代的,它将被强制转换为1以提供可迭代的结果)。例如,这里:
>>> 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,value),我们有一个列表列表[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)因为fun只需要2个参数。因此,在这里,我们的列表[key,key...,value,value]将被提供给zip,因此真正的调用是zip(key,key...,value,value...)……它给了我们想要的东西,一本字典。在这个字典中,我们只需使用键"cache“来获取值。我们就完事了。
这一行很聪明,但读起来并不令人愉快。HuStmpHrrr在问题下面的注释中提供了一种更好的方法来实现这一点。
https://stackoverflow.com/questions/30439616
复制相似问题