是否有存储多选值的首选方法?

Is there a preferred way to store multiselect values?

我需要存储来自多选下拉菜单的数据,并考虑哪种数据结构最简单且最适合存储此类值。我有几个关于如何存储值的想法,但我想问是否有一些首选的 pythonic 方法来解决这个问题(例如,一些 class 用于多选结构)。

#1)
fruits=["Apple","Pear","Apricot","Banana","Orange","Raspberry","Blueberry","Kiwi","Pineapple"]
chosen_fruit_indices=[2,4,5] 
#problem1: need to update indices when fruit list is updated

#2)
fruits=["Apple","Pear","Apricot","Banana","Orange","Raspberry","Blueberry","Kiwi","Pineapple"]
chosen_fruits=["Apricot","Orange","Raspberry"] 
#problem2: need to be updated when fruit list does not contain one of chosen items anymore

#3)
fruits=["Apple","Pear","Apricot","Banana","Orange","Raspberry","Blueberry","Kiwi","Pineapple"]
chosen_fruit_dict={"Apricot":True,"Orange":True,"Raspberry":True}
#problem2: need to be updated when fruit list does not contain one of chosen items anymore
#problem3: problematic duplicate keys in dictionary

#4)
chosen_fruit_dict={"Apple":False,"Pear":False,"Apricot":True,"Banana":False,"Orange":True,"Raspberry":True,
                   "Blueberry":False,"Kiwi":False,"Pineapple":False}
#problem3: problematic duplicate keys in dictionary
#advantage1: one variable is enough to store all the information

这里有一个选项可以让您有效地存储多个水果:

from collections import OrderedDict
chosen_fruit_dict: dict[str, int]  # The fruit as the key and the number of them on the right
chosen_fruit_dict = OrderedDict({"Apple": 3, "Pear": 1, "Apricot": 2})

好处:

  • 更容易调试 - 当调试而不是得到一个类似于["Apple","Apple","Apple","Pear"]的列表时,一个更整洁的OrderedDict([('Apple', 3), ('Pear', 1)])将帮助你清楚地看到发生了什么玩家库存
  • 保留项目的顺序 - 如果要更改原始 fruits 列表,更改 chosen_fruit_dict 不会那么困难
  • 仍然很容易访问 -
    for fruit in chosen_fruit_dict:
        # Do stuff here with every fruit
        for i in range(chosen_fruit_dict[fruit]):
            # Do stuff here with the number of that fruit
    
  • 可以节省一点内存 - 如果您需要非常长的列表,这将是可扩展的

缺点:

  • 在 运行-time 时使用了更多的计算 - 甚至不应该显着到足以引起注意

为了解决这个问题,我想出了一个新的包来解决所有问题:重复值;勾选和未勾选项目的快速子集;并下令添加和删除项目。

可以在这里找到:https://github.com/DovaX/multiselect

使用

可以很容易地安装它
pip install multiselect

用法如下

from multiselect.multiselect_core import Multiselect

fruits=["Apple","Pear","Apricot","Banana","Orange","Raspberry","Blueberry","Kiwi","Pineapple"]

fruit_multiselect=[{"key":"Apple","value":False},{"key":"Pear","value":False},{"key":"Apricot","value":True},{"key":"Banana","value":False},
                   {"key":"Orange","value":True},{"key":"Raspberry","value":True},{"key":"Kiwi","value":False},{"key":"Pineapple","value":False}]


multiselect=Multiselect(fruit_multiselect) #1st way how to initialize

multiselect2=Multiselect.init_from_options(fruits) #2nd way how to initialize
multiselect2.tick_by_indices([2,4,5])

multiselect3=Multiselect.init_from_options(fruits) #3rd way how to initialize
multiselect3.tick_all_by_key("Apricot")
multiselect3.tick_all_by_key("Orange")
multiselect3.tick_all_by_key("Raspberry")

multiselect4=Multiselect.init_from_options(fruits) #4th way how to initialize
multiselect4.tick_all_by_keys(["Apricot","Orange","Raspberry"])


print(multiselect.data)
#[{'key': 'Apple', 'value': False}, {'key': 'Pear', 'value': False}, {'key': 'Apricot', 'value': True}, {'key': 'Banana', 'value': False}, {'key': 'Orange', 'value': True}, {'key': 'Raspberry', 'value': True}, {'key': 'Kiwi', 'value': False}, {'key': 'Pineapple', 'value': False}]

print(multiselect.keys())
#['Apple', 'Pear', 'Apricot', 'Banana', 'Orange', 'Raspberry', 'Kiwi', 'Pineapple']

print(multiselect.values())
#[False, False, True, False, True, True, False, False]

print(multiselect)
#<Multiselect object> [{'key': 'Apple', 'value': False}, {'key': 'Pear', 'value': False}, {'key': 'Apricot', 'value': True}, {'key': 'Banana', 'value': False}, {'key': 'Orange', 'value': True}, {'key': 'Raspberry', 'value': True}, {'key': 'Kiwi', 'value': False}, {'key': 'Pineapple', 'value': False}]

print(multiselect["Apple"])
#False

print(multiselect.items())
#[('Apple', False), ('Pear', False), ('Apricot', True), ('Banana', False), ('Orange', True), ('Raspberry', True), ('Kiwi', False), ('Pineapple', False)]

print(multiselect.get_ticked_indices())
#[2, 4, 5]

print(multiselect.get_unticked_indices())
#[0, 1, 3, 6, 7]