相同的Python代码为相同的输入字典返回不同的结果
我有一本名为dico的字典,其中包含以下信息:相同的Python代码为相同的输入字典返回不同的结果,python,python-3.x,dictionary,python-3.5,Python,Python 3.x,Dictionary,Python 3.5,我有一本名为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+201505
('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
或
或
这是我的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.")
我想知道为什么以及如何纠正它。最后,我所需要的是一个字典,它为元组中的每个包提供最新版本。为同一个包丢失2个值中的1个不是问题。谢谢。这不是对您的问题的直接回答,但您需要解决该问题,以获得工作和可复制的行为。(如果您的bug在修复后消失,我也不会感到震惊) 在代码中:
for key, value in zip(dic.keys(), dic.values())
以及:
这假设键和值按相同顺序排序。这不一定是真的,这会导致基于返回订单的执行差异。
您应该使用项目
:
for key, value in dict.item())
以及:
因此:
成为:
for idx, (x, y) in enumerate(zip(list_keys, list_values)):
或者,更像蟒蛇:
for k, v in package_dictionary.items():
另一个解决方案是使用OrderedDict。这不是问题的直接答案,但您需要解决该问题,以获得工作和可复制的行为。(如果您的bug在修复后消失,我也不会感到震惊) 在代码中:
for key, value in zip(dic.keys(), dic.values())
以及:
这假设键和值按相同顺序排序。这不一定是真的,这会导致基于返回订单的执行差异。
您应该使用项目
:
for key, value in dict.item())
以及:
因此:
成为:
for idx, (x, y) in enumerate(zip(list_keys, list_values)):
或者,更像蟒蛇:
for k, v in package_dictionary.items():
另一个解决方案是使用订购的ICT。我得到了答案
“”“
比较软件包版本并保留最新版本的函数。
@参数:字典
套装词典:
关键字:元组
值:字符串
“”“
导入apt\u软件包
apt_pkg.init_系统()
def比较外翻(x,l):
如果(类型(l)为列表):
最大版本=l[0]
对于范围(1,透镜(l)-1内的e:
#vc=结果反比较版本
vc=apt\u包装版本\u比较(l[e],l[e+1])
如果((vc>0)和(apt软件包版本比较(l[e],最大版本))>0:
#a> b
最大版本=l[e]
elif((vc==0)和(apt软件包版本比较(l[e],最大版本))>0):
#a==b
最大版本=l[e]
elif((vc<0)和(apt软件包版本比较(最大版本,l[e+1]))<0):
#我得到了答案
“”“
比较软件包版本并保留最新版本的函数。
@参数:字典
套装词典:
关键字:元组
值:字符串
“”“
导入apt\u软件包
apt_pkg.init_系统()
def比较外翻(x,l):
如果(类型(l)为列表):
最大版本=l[0]
对于范围(1,透镜(l)-1内的e:
#vc=结果反比较版本
vc=apt\u包装版本\u比较(l[e],l[e+1])
如果((vc>0)和(apt软件包版本比较(l[e],最大版本))>0:
#a> b
最大版本=l[e]
elif((vc==0)和(apt软件包版本比较(l[e],最大版本))>0):
#a==b
最大版本=l[e]
elif((vc<0)和(apt软件包版本比较(最大版本,l[e+1]))<0):
#a您需要向我们展示—符合您的数据格式的最小dict文本、此数据的预期结果以及当前代码返回的输出。字典是无序的,每次运行Python解释器都会生成一个新的随机哈希种子,以防止恶意的DOS攻击(攻击者很容易使您的Python进程过载). 因此,将键与“下一个”键进行比较是行不通的。@MartijnPieters-。。。一个新的随机散列种子被产生,以防止一类恶劣的拒绝服务攻击。。。我想更好地理解这一点。可以提供一些详细解释这一点的资源链接吗?@JasonEstibeiro:请参阅中的方框注释。我注意到我无法比较两个键,这就是为什么我创建了一个键列表和一个值列表。我必须比较字典键中存在多次的包的版本。您需要向我们显示-符合您的数据格式的最小dict文本、此数据的预期结果以及代码当前返回的输出。字典无序,每次运行Python解释器都会生成一个新的随机散列种子,以防止恶意的DOS攻击(攻击者很容易使Python进程过载)。因此,将键与“下一个”键进行比较是行不通的。@MartijnPieters-。。。一个新的随机散列种子被产生,以防止一类恶劣的拒绝服务攻击。。。我想更好地理解这一点。可以提供一些详细解释这一点的资源链接吗?@JasonEstibeiro:请参阅中的方框注释。我注意到我无法比较两个键,这就是为什么我创建了一个键列表和一个值列表。我必须比较字典密钥中存在多次的包的版本。谢谢您的回答。我按照你的建议做了,但是当我列出\u键,list\u values=list(package\u dictionary.items())时,我得到了一个ValueError:太多的值无法解包(预期为2个)。键和值按相同的顺序排序,前提是没有对字典进行编辑。但是,在解释器的两次运行之间,它们的顺序将不同。@Marc:请按照此答案中所述更新for
循环。然而,这个答案并不能解决你的问题;如果您每次都以相同的顺序将条目传递到OrderedDict
中,则可能会对您有所帮助。事实上,我做了一个测试,以验证条目是否已排序,并且是否正确。x和y的值相同。但是我确实用@aluriak建议的一切更新了我的代码。对于zip中的x,y(范围(0,len(list_键)-1),范围(0,len(list_值)-1))必须保留,因为我需要访问typle内容和
for idx, (x, y) in enumerate(zip(list_keys, list_values)):
for k, v in package_dictionary.items():
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.")