如何在 ipywidgets 下拉列表或 Select 中排序条目?

How to order entries in ipywidgets Dropdown or Select?

我想 select 从可能的 float 类型值列表中:

values = [400e-9,435e-9,498e-9]

ipywidgets 模块提供 Select 和 Dropdown 小部件,它们接受字符串列表或字典。在后一种情况下,将显示键,并在 selected 相应键时使用值。参见 the list of widgets in the docs

# Required imports for examples below
import ipywidgets as widgets
from IPython.display import display

事实上,直接提供我的值列表会引发错误,因为这些值是浮点数,而不是字符串。

# This will raise a TraitError
w = widgets.Select(options=values,description='Select one of the values:')
display(w)

所以我创建了一个字典并将其传递给小部件:

keys = ["{:.2e}".format(val) for val in values]
valsdict = dict(zip(keys,values))
w = widgets.Select(options=valsdict, description='Select one of the values:')
display(w)

但是,由于字典未排序,生成的小部件以看似 运行dom 顺序显示选项。在这种情况下,当我 运行 它时,498e-9 排在 435e-9 之前,如屏幕截图所示:screenshot of the resulting widget.

所以问题是,有没有办法对 selection 小部件中的条目进行排序?

一个明显的解决方法是只为小部件提供我的字符串列表(在上面的示例中称为 keys)并自己从列表中查找相应的值,但我希望会有更优雅的解决方案。

你可以传递一个元组列表:

vals = list(zip(keys,values))
w = widgets.Select(options=vals, description='Select one of the values:')

另外两个要考虑的选项:

  1. 将值从浮点数映射到字符串:

    w = widgets.Select(options=map(str,values), description='Select one of the values:')
    

    在我看来,这比创建一个以值的字符串作为键的字典更为惯用。它也更短 :).

  2. 使用有序字典:

    from collections import OrderedDict
    names = map(str,values)
    od_vals = OrderedDict(zip(names,values))
    w = widgets.Select(options=od_vals, description='Select one of the values:')
    

    这里的优点是列表 names 可以是任何你想要的,例如names=['choice 1','choice 2','choice 3']。然后,这允许您获得 od_vals[w.selected_label] 选择的值,这对于方法 1 或您接受的答案是不可能的。