简体   繁体   English

检查字典中是否已经存在两个数字作为一个键(Python)

[英]Checking if two numbers as one key are already in a dictionary (Python)

I'm trying to store the LCM of two numbers in a dictionary to perform the calculation only if it has not been completed yet aka is already stored in the dictionary.我正在尝试将两个数字的 LCM 存储在字典中,以便仅在尚未完成的情况下执行计算,也就是已存储在字典中。 I take the numbers a and b as key and try to check in my code if they already exist as key.我将数字 a 和 b 作为键,并尝试检查我的代码是否已作为键存在。 Exactly there it fails with me, because I don't know, how I should define the two numbers as a key.正是在那里,我失败了,因为我不知道应该如何将两个数字定义为键。 It should not matter if a=7 , b=8 or a=8 and b=7.如果 a=7 , b=8 或 a=8 和 b=7 应该无关紧要。 Thanks for the help!谢谢您的帮助! The exact position is marked in the code具体位置在代码中标明



a = int(input("Give A: "))
b = int(input("Give B: "))

dic = {}





while a != 0 and b != 0:

#my problem is here!
    
    if (a,b)in dic.keys():
        print("Found in dictionary!")
        print("LCM for ", a, " and ", b, " is ", dic[a,b])
        
        a = int(input("Give A: "))
        b = int(input("Give B: "))
        
   # choose the greater number
   
   
   
    else:
        if a > b:
            greater = a
        else:
            greater = b

        while(True):
            if((greater % a == 0) and (greater % b == 0)):
                lcm = greater
                #adding lcm to dic with the keys a and b
                dic[a,b] = (lcm)
                print ("Not found in dictionary!")
                print("LCM for ", a, " and ", b, " is ", dic[a,b])
                break
                
            else:           
                greater += 1
                
        a = int(input("Give A: "))
        b = int(input("Give B: "))
        
    
        
print ("Terminated + the values added so far were: " , dic)

If you want to compare collections where order doesn't matter, a set is usually what you want.如果您想比较顺序无关紧要的集合,通常需要一个集合。 set(a, b) is equal to set(b, a) set(a, b) 等于 set(b, a)

However, sets are unhashable types, so you won't be able to use them as dictionary keys.但是,集合是不可散列的类型,因此您将无法将它们用作字典键。 Instead, you can use a frozenset, which will work the same, but its immutable.相反,您可以使用frozenset,它的工作方式相同,但不可变。 Because it is immutable, it will be a hashable type, and can be used as a dictionary key.因为它是不可变的,它将是一个可散列的类型,并且可以用作字典键。

https://docs.python.org/3/library/stdtypes.html#frozenset https://docs.python.org/3/library/stdtypes.html#frozenset

Note that this will be slightly weird if a == b.请注意,如果 a == b,这将有点奇怪。 Sets only store unique values, so set(5, 5) will be equal to set(5).集合只存储唯一值,因此 set(5, 5) 将等于 set(5)。 This will still be mathematically correct in your use case, since lcm(5, 5) is the same as lcm(5), but its something to keep in mind if eg.在您的用例中,这在数学上仍然是正确的,因为 lcm(5, 5) 与 lcm(5) 相同,但是如果例如,请记住它。 The number of elements in the collection is relevant集合中元素的数量是相关的

I think the best way of storing data will be in list.我认为存储数据的最佳方式是列表。 If you are not forced to use dictionary in some way, just don't.如果您不是被迫以某种方式使用字典,请不要使用。 Put dict away in this case.在这种情况下把 dict 放在一边。 You don't need to have variable a and b as key.您不需要将变量ab作为键。 Just simple create a nested list (eg data = [[7, 8, 56], [6, 5, 30]] ).只需简单地创建一个嵌套列表(例如data = [[7, 8, 56], [6, 5, 30]] )。

First create variable where you will be storing input data.首先创建变量,您将在其中存储输入数据。 Then, if variable does not contain new input simply add it in a format [a, b, lcm] .然后,如果变量不包含新输入,只需以[a, b, lcm]格式添加它。

a = int(input("Give A: "))
b = int(input("Give B: "))

data = []

while a != 0 and b != 0:

    match = False   
    for item in data:   # iterate list

        if item[0] == a and item[1] == b:   # if match, store lcm
            match = item[2]
            break
    
    if match:
        print("Found in dictionary!")
        print("LCM for ", a, " and ", b, " is ", match)
        
        a = int(input("Give A: "))
        b = int(input("Give B: "))
        

    else:
        if a > b:
            greater = a
        else:
            greater = b

        while(True):
            if((greater % a == 0) and (greater % b == 0)):
                lcm = greater
                data.append([a, b, lcm])    # Append to the list

                print("Not found in dictionary!")
                print("LCM for ", a, " and ", b, " is ", lcm)
                break
                
            else:           
                greater += 1
                
        a = int(input("Give A: "))
        b = int(input("Give B: "))
        
    
        
print ("Terminated + the values added so far were: " , data)

Hope it helped!希望有帮助!

Dunno the best answer, but I'd suggest using a dict subclass for this.不知道最好的答案,但我建议为此使用dict子类。 Something like this:像这样的东西:

class SortedTupleDict(dict):

    def __setitem__(self, key, value):
        super().__setitem__(tuple(sorted(key)), value)

    def __getitem__(self, item):
        return super().__getitem__(tuple(sorted(item)))

    def __contains__(self, item):
        return super().__contains__(tuple(sorted(item)))


d = SortedTupleDict()
d[(3, 1)] = 'test'
print(d)  # {(1, 3): 'test'}

# True
assert d[(3, 1)] == d[(1, 3)] == 'test'
assert (3, 1) in d

What it's doing here is sorting the elements in the tuple from lowest to highest, so (4, 1, 2) is stored as (1, 2, 4) .它在这里所做的是将tuple的元素从低到高排序,因此(4, 1, 2)存储为(1, 2, 4) Then when retrieving an item by a key, it sorts the tuple and then looks it up in the dict object.然后当通过键检索一个项目时,它对元组进行排序,然后在dict对象中查找它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM