Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 递归遍历多维字典并导出到csv_Python_Dictionary_Multidimensional Array_Export To Csv - Fatal编程技术网

Python 递归遍历多维字典并导出到csv

Python 递归遍历多维字典并导出到csv,python,dictionary,multidimensional-array,export-to-csv,Python,Dictionary,Multidimensional Array,Export To Csv,我有一个复杂的多维字典,我想将一些键值对导出到一个csv文件,作为一个运行日志文件。我尝试了导出到cvs函数的各种帮助,并在stackoverflow中对遍历多维字典的大部分代码示例进行了黑客攻击,但未能找到解决方案。这个问题也很独特,因为它只有一些我想要导出的键值 这是字典: cpu_stats = {'time_stamp': {'hour': 22, 'month': 5, 'second': 43, 'year': 2014, 'day': 29, 'minute': 31}, 'cpu

我有一个复杂的多维字典,我想将一些键值对导出到一个csv文件,作为一个运行日志文件。我尝试了导出到cvs函数的各种帮助,并在stackoverflow中对遍历多维字典的大部分代码示例进行了黑客攻击,但未能找到解决方案。这个问题也很独特,因为它只有一些我想要导出的键值

这是字典:

cpu_stats = {'time_stamp': {'hour': 22, 'month': 5, 'second': 43, 'year': 2014, 'day': 29, 'minute': 31}, 'cpus': [[{'metric_type': 'CPU_INDEX', 'value': 1}, {'metric_type': 'CPU_TEMPERATURE', 'value': 39}, {'metric_type': 'CPU_FAN_SPEED', 'value': 12000}]]}
我需要将时间戳中的值格式化为yyyy-mm-dd hh:mm:ss,并将其存储为行的第一个单元格。然后,我需要“CPU”中的值作为时间戳所在行的CPU索引、CPU温度和CPU风扇速度

csv文件应如下所示:

time_stamp, cpu_index, cpu_temperature, cpu_fan_speed
2014-05-29, 1, 38, 12000
t = cpu_stats['time_stamp']
date = '{}-{}-{}'.format(t['year'], t['month'], t['day'])
for cpu in cpu_stats['cpus']:
    c = {d['metric_type']: d['value'] for d in cpu}
    row = [date, c['cpu_index'], c['cpu_temperature'], c'[cpu_fan_speed']]
我一直在研究的一个例子是:

def walk_dict(seq, level=0):
"""Recursively traverse a multidimensional dictionary and print all
keys and values.
"""

items = seq.items()
items.sort()
for v in items:
    if isinstance(v[1], dict):
        # Print the key before make a recursive call
        print "%s%s" % ("  " * level, v[0])
        nextlevel = level + 1
        walk_dict(v[1], nextlevel)
    else:
        print "%s%s %s" % ("  " * level, v[0], v[1])
我得到以下输出

walk_dict(cpu_stats)

cpus [[{'metric_type': 'CPU_INDEX', 'value': 1}, {'metric_type': 'CPU_TEMPERATURE', 'value': 38}, {'metric_type': 'CPU_FAN_SPEED', 'value': 12000}]]
time_stamp
  day 29
  hour 22
  minute 17
  month 5
  second 19
  year 2014
我也一直在破解这个函数,希望我可以将日期信息存储到变量中,然后将这些变量格式化为单个字符串。不幸的是,它有递归调用,这会在后续调用中释放局部变量。使用全球战略是徒劳的

def parseDictionary(obj, nested_level=0, output=sys.stdout):

spacing = '   '
if type(obj) == dict:
    print >> output, '%s{' % ((nested_level) * spacing)
    for k, v in obj.items():
        if hasattr(v, '__iter__'):
            # 1st level, prints time and cpus
            print >> output, '%s:' % (k)
            parseDictionary(v, nested_level + 1, output)
        else:
            # here is the work
            if k == "hour":
                hour = v
            elif k == "month":
                month = v
            elif k == "second":
                second = v
            elif k == "year":
                year = v
            elif k == "day":
                day = v
            elif k == "minute":
                minute = v
            print >> output, '%s %s' % (k, v)
    print >> output, '%s}' % (nested_level * spacing)
elif type(obj) == list:
    print >> output, '%s[' % ((nested_level) * spacing)
    for v in obj:
        if hasattr(v, '__iter__'):
            parseDictionary(v, nested_level + 1, output)
        else:
            print >> output, '%s%s' % ((nested_level + 1) * spacing, v)
    print >> output, '%s]' % ((nested_level) * spacing)
else:
    print >> output, '%s%s' % (nested_level * spacing, obj)


if __name__ == "__main__":
    global year
    global month
    global day
    global hour
    global minute
    global second

    cpu_stats = {'time_stamp': {'hour': 22, 'month': 5, 'second': 43, 'year': 2014, 'day': 29, 'minute': 31}, 'cpus': [[{'metric_type': 'CPU_INDEX', 'value': 1}, {'metric_type': 'CPU_TEMPERATURE', 'value': 39}, {'metric_type': 'CPU_FAN_SPEED', 'value': 12000}]]}
    parseDictionary(cpu_stats)
    print '%s-%s-%s %s:%s:%s' % (year, month, day, hour, minute, second)
输出:

{
time_stamp:
   {
hour 22
month 5
second 27
year 2014
day 29
minute 57
cpus:
   [
      [
         {
metric_type CPU_INDEX
value 1
         {
metric_type CPU_TEMPERATURE
value 39
         {
metric_type CPU_FAN_SPEED
value 12000
      ]
   ]
Traceback (most recent call last):
  File "./cpu.py", line 135, in <module>
    print '%s-%s-%s %s:%s:%s' % (year, month, day, hour, minute, second)
NameError: global name 'year' is not defined
{
时间戳:
{
第22小时
第5个月
第二个27
2014年
第29天
第57分钟
CPU:
[
[
{
度量型CPU索引
值1
{
公制CPU型CPU温度
价值39
{
公制CPU风扇转速
价值12000
]
]
回溯(最近一次呼叫最后一次):
文件“/cpu.py”,第135行,在
打印“%s-%s-%s%s:%s:%s%”(年、月、日、时、分、秒)
NameError:未定义全局名称“年”

谢谢,我非常感谢您能为我指明正确的方向,因为我目前正不知所措。

我认为您可能没有理解字典的意义。与其反复查看字典的键并检查它是否是您想要的键,不如只查找您想要的键。这样处理问题可能会更容易:

time_stamp, cpu_index, cpu_temperature, cpu_fan_speed
2014-05-29, 1, 38, 12000
t = cpu_stats['time_stamp']
date = '{}-{}-{}'.format(t['year'], t['month'], t['day'])
for cpu in cpu_stats['cpus']:
    c = {d['metric_type']: d['value'] for d in cpu}
    row = [date, c['cpu_index'], c['cpu_temperature'], c'[cpu_fan_speed']]
如果您将
CPU
值作为字典列表,而不是字典列表,并将时间戳存储为datetime对象,生活会更轻松:

cpu_stats = {'time_stamp': datetime.datetime(2014, 5, 29, 22, 31, 43), 'cpus': [{'CPU_INDEX': 1, 'CPU_TEMPERATURE': 39, 'CPU_FAN_SPEED': 12000}]}

如果你把字典埋在一个像
{'key\u name':'my\u key','key\u value':'my\u value'}
这样的结构中,它的全部意义都会丢失。这只是增加了一个你不需要的额外层,而你只需要:
{'my\u key':'my\u value'}

我同意@desired login,但是假设您无法控制传入的数据,并且必须处理您在问题中显示的内容……您可以像这样遍历它:

cpu_stats = {'time_stamp': {'hour': 22, 'month': 5, 'second': 43, 'year': 2014, 'day': 29, 'minute': 31}, 
             'cpus': [ [{'metric_type': 'CPU_INDEX', 'value': 1}, {'metric_type': 'CPU_TEMPERATURE', 'value': 39}, {'metric_type': 'CPU_FAN_SPEED', 'value': 12000} ] ] 
            }

timestamp = ''
for stats in cpu_stats.keys():
    if stats == 'time_stamp':
        timestamp = '{year}-{month}-{day}'.format(**cpu_stats[stats])
    if stats == 'cpus':
        for cpu in cpu_stats[stats]:
            cpu_index = ''
            cpu_temperature = ''
            cpu_fan_speed = ''
            for metric in cpu:
                if metric['metric_type'] == 'CPU_INDEX':
                    cpu_index = str(metric['value'])
                elif metric['metric_type'] == 'CPU_TEMPERATURE':
                    cpu_temperature = str(metric['value'])
                elif metric['metric_type'] == 'CPU_FAN_SPEED':
                    cpu_fan_speed = str(metric['value'])
            print ','.join([timestamp, cpu_index, cpu_temperature, cpu_fan_speed])

感谢您的帮助和信息性帮助。字典是使用iControl从F5负载平衡器中提取的。遗憾的是,它以这种方式存储在dict变量中,我对此没有控制权。我只需要尝试围绕它进行编码,这是最大的挑战,因为时间戳和CPU就像两个不同的字典谢谢woot,这个解决方案很好用,我更喜欢它的可读性。