首页 > 解决方案 > 在 pygal Worldmaps 中生成值格式化程序的 Python 问题

问题描述

我有一本国名字典,对于每个国家,我都存储了一个数值和一个标签。数值是我传递给 pygal Worldmap 的简单频率,标签是我想添加到工具提示的字符串。

例如假设国家'af'和'cn'有对应的数值20和10,标签'AA'和'BB'。然后下面的代码工作得很好。

import pygal
worldmap_chart = pygal.maps.world.World()

worldmap_chart.add('2012', [{'value': ('af',20), 
                              'formatter': lambda x: '{}: {}'.format(x[0], x[1]) + 'AA'},
                            {'value': ('cn',10), 
                              'formatter': lambda x: '{}: {}'.format(x[0], x[1]) + 'BB'}])

但是如果我创建一个这样的列表

countries=[{'value': ('af',20), 'tag':'AA'}, {'value': ('cn',10), 'tag':'BB'}]

并像这样将它传递给上面的函数

worldmap_chart.add('2012', [{'value': i['value'], 
                      'formatter': lambda x: '{}: {}'.format(x[0], x[1]) + i['tag']} for i in countries])

它没有给我同样的东西!现在,两个工具提示都显示BBcountries.

事实上,我有几十个国家和最后一个代码,工具提示都是一样的,它们是最后一个国家的标签。但顶部的第一个代码工作正常,我想知道如何正确生成它们。

标签: pythonpython-3.xlambdastring-formattingpygal

解决方案


变量i正在改变。直到稍后才调用formatter函数,此时i已经指向 for 循环的最后一个元素。如果您可以在它完成第一个元素之后并在它继续到第二个元素之前直接调用格式化程序,您将得到AA. 您需要做的是绑定i['tag']到 lambda 的参数 -tag=i["tag"]以便保存值本身。

def main():
    countries=[{'value': ('af',20), 'tag': 'AA'}, 
               {'value': ('cn',10), 'tag': 'BB'}]
    regular = [{'value': ('af',20), 'formatter': lambda x: f'{x[0]}: {x[1]}AA'},
               {'value': ('cn',10), 'formatter': lambda x: f'{x[0]}: {x[1]}BB'}]
    generated = [{'value': i['value'],
                  'formatter':
                      lambda x, tag=i["tag"]:
                      f'{x[0]}: {x[1]}{tag}'} for i in countries]

    print(regular[0]['formatter']((5, 3)))
    print(generated[0]['formatter']((5, 3)))


if __name__ == '__main__':
    main()

它打印的是:

5: 3AA
5: 3AA

推荐阅读