python3:避免在字典中创建重复键

2024-10-01 19:15:39 发布

您现在位置:Python中文网/ 问答频道 /正文

下面是我的示例代码:

#!/usr/bin/env python3

LIST_OF_UNITS = {}

class Unit():
    def __init__(self,name, value):
       self.name = name
       self.value = value

def create_new_unit(name, value):
    return Unit(name, value)

def add_new_unit(d, name, value):
    d[name] = Unit(name, value)
    return d

unit = create_new_unit('reactor1', 1)
LIST_OF_UNITS[unit.name] = unit

unit = create_new_unit('reactor2', 2)
LIST_OF_UNITS[unit.name] = unit

LIST_OF_UNITS = add_new_unit(LIST_OF_UNITS, 'reactor3', 3)

print(LIST_OF_UNITS)

LIST_OF_UNITS = add_new_unit(LIST_OF_UNITS, 'reactor3', 4)

print(LIST_OF_UNITS)

如你所见,我有两种向字典添加对象的方法。还不知道哪个更好。解决我的问题可能更灵活些。所以,我把它们都包括进去了。你知道吗

我想建立一个反应堆及其属性的列表。你知道吗

对于每个reactor,我创建一个对象,该对象最终将包含该reactor的属性(比如它的体积、操作开始和结束时间等)

我想防止(重复)创建一个单元。在本例中,应避免创建值4的“reactor3”。你知道吗

最好的办法是什么。在类内部,使用其中一个方法还是其他方法?你知道吗

非常感谢您的真知灼见。你知道吗


Tags: of对象方法nameselfaddnewvalue
3条回答

如果向词典中添加具有相同键的条目,则该条目将被覆盖,因此将丢失其中一个条目。你知道吗

如果要避免这种情况,可以检查名称是否已经在字典的键值中。你知道吗

这个怎么样?你知道吗

if name in LIST_OF_UNITS.keys():
   # raise an error
else:
   pass

如果您更改一些代码,您可以将所有创建的Unit作为类变量存储在Unit中。工厂方法应该是classmethods,并将自动向其中添加/创建实例。你知道吗

class Unit():
    UNITS = {} # shared btw. instances

    def __init__(self, name, value):
        self.name = name 
        self.value = value

    # nicer output
    def __repr__(self): return "{} - {}".format(self.name, self.value)    
    def __str__(self):  return repr(self) 

# this should be a classmethod instead, depending on your usage you might want to
# raise Errors instead of returning existing instances
def create_new_unit(name, value):
    # create if needed, else return the one already in
    # does not alter Unit.value if present
    u = Unit.UNITS.setdefault(name, Unit(name,value))
    if u.value != value:
        raise ValueError("Unit '{}' exists with different value".format(name))
    else:
        return u

# this should be a classmethod instead, depending on your usage you might want to
# raise Errors instead of returning existing instances    def add_new_unit(name, value):
    # create new unit or alter an existing Unit's value
    # you should rename the method accordingly
    u = Unit.UNITS.setdefault(name, Unit(name,value)) 
    u.value = value  # change it if called again 
    return Unit.UNITS

unit1 = create_new_unit('reactor1', 1) 

unit2 = create_new_unit('reactor2', 2) 

all_units = add_new_unit('reactor3', 3)

for u in Unit.UNITS:
    print(id(Unit.UNITS[u]),Unit.UNITS[u]) 

all_units = add_new_unit('reactor3', 4)

for u in Unit.UNITS:
    print(id(Unit.UNITS[u]),Unit.UNITS[u]) 

输出:

140125186245968 reactor1 - 1
140125186246024 reactor2 - 2
140125186246080 reactor3 - 3

140125186245968 reactor1 - 1
140125186246024 reactor2 - 2
140125186246080 reactor3 - 4 # changed by add_new_unit


# if create_new_unit(..) same named unit again with different value:
# ValueError: Unit 'reactor2' exists with different value 

就我个人而言,我建议不要创建多个实例化新方法的方法。我可能会把“工厂方法”作为@classmethods,而不是放在普通程序中。这样Unit的所有内务处理都由 Unit类本身,您可以将逻辑集中在它所属的位置,而不必在主程序中添加创建的单元。你知道吗

建议阅读@classmethodMeaning of @classmethod and @staticmethod for beginner?

只要检查一下这个项目是否已经在字典的键中。仅当尚未插入时插入。你知道吗

def add_new_unit(d, name, value):
    if(name in d.keys()):
        print("The reactor information for {name} already recorded!".format(name = name))
        return d
    d[name] = Unit(name, value)
    return d

相关问题 更多 >

    热门问题