繁体   English   中英

相同的Python代码对于相同的输入字典返回不同的结果

[英]Same Python code returns different results for same input dictionary

我有一本名为dico的字典,其中包含以下信息:

('libc6-i386', '1.06')  :  lib32tinfo5
('lib32c-dev', '')  :  lib32tinfo-dev
('libc6-x32', '2.16')  :  libx32tinfo5
('libc6-i386', '2.4')  :  lib32ncursesw5
('libc-dev', '')  :  libncursesw5-dev
('libncurses5-dev', '5.9+20150516-2ubuntu1')  :  libncurses5-dbg
('libc6-dev', '')  :  libncursesw5-dev
('libc6-dev-x32', '')  :  libx32tinfo-dev
('libc6-i386', '2.16')  :  lib32tinfo5
('libncursesw5-dev', '5.9+20150516-2ubuntu1')  :  libncursesw5-dbg

当我调用comparePackages(dico)时,对于相同的输入,我不断得到不同的结果,例如:

('lib32c-dev', 'Not Specified') lib32tinfo-dev
('libc6-dev', 'Not Specified') libncursesw5-dev
('libc-dev', 'Not Specified') libncursesw5-dev
('libc6-i386', '2.4') lib32ncursesw5
('libc6-x32', '2.16') libx32tinfo5
('libncurses5-dev', '5.9+20150516-2ubuntu1') libncurses5-dbg
('libc6-dev-x32', 'Not Specified') libx32tinfo-dev
('libc6-i386', '2.16') lib32tinfo5
('libncursesw5-dev', '5.9+20150516-2ubuntu1') libncursesw5-dbg

要么

('libncurses5-dev', '5.9+20150516-2ubuntu1') libncurses5-dbg
('libncursesw5-dev', '5.9+20150516-2ubuntu1') libncursesw5-dbg
('libc6-i386', '2.16') lib32tinfo5
('lib32c-dev', 'Not Specified') lib32tinfo-dev
('libc6-x32', '2.16') libx32tinfo5
('libc6-dev', 'Not Specified') libncursesw5-dev
('libc6-i386', '2.4') lib32ncursesw5
('libc-dev', 'Not Specified') libncursesw5-dev

要么

('libc6-i386', '2.4') lib32ncursesw5
('libc-dev', 'Not Specified') libncursesw5-dev
('libc6-i386', '1.06') lib32tinfo5
('lib32c-dev', 'Not Specified') lib32tinfo-dev
('libncurses5-dev', '5.9+20150516-2ubuntu1') libncurses5-dbg
('libncursesw5-dev', '5.9+20150516-2ubuntu1') libncursesw5-dbg
('libc6-i386', '2.16') lib32tinfo5
('libc6-dev', 'Not Specified') libncursesw5-dev
('libc6-x32', '2.16') libx32tinfo5

这是我的comparePackages函数

import apt_pkg
apt_pkg.init_system()

"""
    Function that compares package versions and keeps the most recent one.
    @param : dictionary
        package_dictionary :
            keys : tuple
            values : string
"""

def comparePackages(package_dictionary):
    if(type(package_dictionary) is dict):
        list_keys = list(package_dictionary.keys()) #list of tuples
        list_values = list(package_dictionary.values()) #list of strings
        #list_keys, list_values = list(package_dictionary.items())
        dic = {}

        for x,y in zip(range(0,len(list_keys)-1),range(0,len(list_values)-1)):
            #if 2 tuples have the same package name
            if(list_keys[x][0] == list_keys[x+1][0]):
                print("Start comparing")

                #second element of the tuple x
                a = str(list_keys[x][1])

                #second element of the tuple x+1
                b = str(list_keys[x+1][1])

                #compare versions
                vc = apt_pkg.version_compare(a,b)

                if vc > 0:
                    #a>b
                    print("a>b")
                    max_version = a

                elif vc == 0:
                    #a==b
                    print("a==b")
                    max_version = a 

                elif vc < 0:
                    #a<b
                    print("a<b")
                    max_version = b

                if(max_version is '') :
                    max_version = 'Not Specified'
                #create a dict that for each package name has the most recent version
                dic[(list_keys[x][0],max_version)] = list_values[y]

            else:
                version = list_keys[x][1]
                if(version is '') :
                    version = 'Not Specified'
                dic[(list_keys[x][0],version)] = list_values[y]

        for k,v in dic.items():
            print(k,v)

    else:
        raise TypeError("Argument of comparePackages must be a dictionary.")

预期产量:

('lib32c-dev', 'Not Specified')  :  lib32tinfo-dev
('libc6-x32', '2.16')  :  libx32tinfo5
('libc-dev', 'Not Specified')  :  libncursesw5-dev
('libncurses5-dev', '5.9+20150516-2ubuntu1')  :  libncurses5-dbg
('libc6-dev', 'Not Specified')  :  libncursesw5-dev
('libc6-dev-x32', 'Not Specified')  :  libx32tinfo-dev
('libc6-i386', '2.16')  :  lib32tinfo5 (or lib32ncursesw5)
('libncursesw5-dev', '5.9+20150516-2ubuntu1')  :  libncursesw5-dbg

我想知道为什么以及如何纠正它。 最后,我只需要一本字典,该字典对于元组中存在的每个包都具有最新版本。 对于同一包,松开2个值中的1个不是问题。 谢谢。

这不是您问题的直接答案,但是您需要解决该问题才能获得正常工作和可复制的行为。 (如果您的错误在此修复后消失,我也不会感到震惊)

在您的代码中:

for key, value in zip(dic.keys(), dic.values())

和:

list_keys = list(package_dictionary.keys()) #list of tuples
list_values = list(package_dictionary.values()) #list of strings

假定键和值以相同顺序排序。 不一定是正确的,这导致基于返回的订单的执行差异。 您应该改用以下items

for key, value in dict.item())

和:

list_keys, list_values = list(package_dictionary.items())

所以:

for x,y in zip(range(0,len(list_keys)-1),range(0,len(list_values)-1))

成为:

for idx, (x, y) in enumerate(zip(list_keys, list_values)):

或者,更多pythonic:

for k, v in package_dictionary.items():

另一种解决方案是使用OrderedDict。

我得到了答案

“”“比较软件包版本并保留最新版本的函数。@param:字典package_dictionary:键:元组值:字符串”“”

import apt_pkg
apt_pkg.init_system()

def compareVersion(x,l):
    if(type(l) is list):
        max_version = l[0]
        for e in range(1, len(l)-1):
            #vc = resultat de compare versions
            vc = apt_pkg.version_compare(l[e],l[e+1])

            if ((vc > 0) and (apt_pkg.version_compare(l[e],max_version)) > 0):  
                #a>b
                max_version = l[e]

            elif ((vc == 0) and (apt_pkg.version_compare(l[e],max_version)) > 0):
                #a==b
                max_version = l[e] 

            elif ((vc < 0) and (apt_pkg.version_compare(max_version,l[e+1])) < 0):
                #a<b
                max_version = l[e+1]

        if(max_version is '') :
            max_version = 'Not Specified'
                #create a dict that for each package name has the most recent version
        #print(x,l,max_version)
        return max_version
    else:
        raise TypeError("Argument must be a list.")


def comparePackages(package_dictionary):
    if(type(package_dictionary) is dict):
        list_keys = list(package_dictionary.keys()) #list of tuples
        list_values = list(package_dictionary.values()) #list of strings

        dic = {}

        for x in list_keys: #for each element in the list
            l = []
            for h in list_keys:
                if x[0] == h[0]: #if nom package x == nom package h
                    a = str(x[1]) #a = version du package x
                    b = str(h[1]) #b = version du package y
                    if(l.count(a) == 0):
                        l.append(a)
                    if(l.count(b) == 0):
                        l.append(b)
            max_version = compareVersion(x,l)   
            dic[(x[0],max_version)] = list_values[list_keys.index(x)]

        return dic    
    else:
        raise TypeError("Argument of comparePackages must be a dictionary.")    

暂无
暂无

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

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