我需要将字典与值进行比较,以找到匹配的所有值并将其添加出来。问题是我有很大的字典,我的代码很慢。有没有更好的方法来做到这一点或改善我的代码时间?
import itertools
import copy
Dic = {
0: ['-1','A','B','p','r'],
1: ['-','q','p','r'],
2: ['-1','K','q','p','r'],
3: ['+','q','p','r'],
4: ['1','B','q','p','r'],
5: ['-','K','q','p','r'],
}
def S_Sing(SX_Sing,SY_Sing):
if SX_Sing=='+' or SX_Sing=='-':
XX_L=[SX_Sing]
elif SX_Sing!='+' or SX_Sing!='-':
XX_L=SX_Sing
if SY_Sing=='+' or SY_Sing=='-':
YY_L=[SY_Sing]
elif SY_Sing!='+' or SY_Sing!='-':
YY_L=SY_Sing
if XX_L==['+'] or XX_L==['-']:
XX_L.append('1')
if YY_L==['+'] or YY_L==['-']:
YY_L.append('1')
Final=int(''.join(XX_L))+int(''.join(YY_L))
Sum_Final=str(Final)
return Sum_Final
def Comp_Dict_Itself(DicX1):
D_itself_F={}
D_clone= copy.deepcopy(DicX1)
Dic_to_Lista=[]
for k,v in D_clone.iteritems():
Dic_to_Lista.append(v)
for a, b in itertools.combinations(Dic_to_Lista, 2):
if a[:1]!='0' and b[:1]!='0' :
if a[1:]==b[1:]:
S_Final=S_Sing(a[:1],b[:1])
if S_Final==0:
b[:]='0'
a[:]='0'
if S_Final!=0:
b[0]='0'
a[0]=S_Final
somelist_F = [x for x in Dic_to_Lista if x[0]!='0']
for pos, item in enumerate(somelist_F ):
if item[0]!='0':
D_itself_F[pos]= item
return D_itself_F
print(Comp_Dict_Itself(Dic))
输出:
{0: ['-1', 'A', 'B', 'p', 'r'], 1: ['-2', 'K', 'q', 'p', 'r'], 2: ['1', 'B', 'q', 'p', 'r']}
代码所做的是首先检查每个值,以便添加v[1:]
值对于考虑的密钥需要相同的值。键A和B. v[0]
只是一个常量,表示列表重复的次数。然后v[0]
取决于其符号和值,将添加或减去例如vA[0]='1'
或vA[0]='+'
以及vB[0]='-1'
或vB[0]='-'
则新vA[0]
和vB[0]
将为0
,但如果vA[0]=1
}和vB[0]=1
然后新值将为vA[0]=2
和vB[0]=0
。然后,将删除值为0
的键
答案 0 :(得分:0)
好的,我试图了解你的代码,看起来你正在做相当于以下的事情,我希望它更简单,更清晰,至少更有效率:
import itertools as it
def sign_to_num(val):
if val == '+':
return 1
elif val == '-':
return -1
return int(val)
def item_sum(left_val, right_val):
return sign_to_num(left_val) + sign_to_num(right_val)
def comp_dict_itself(d):
values = [list(v) for v in d.values()]
for a, b in it.combinations(values, 2):
if a[0] != '0' != b[0] and a[1:] == b[1:]:
a[0] = str(item_sum(a[0], b[0]))
b[0] = '0'
return dict(enumerate(v for v in values if v[0] != '0'))
注意:
代码中的比较:if a[:1] != '0' and b[:1] != '0'
没用,因为条件始终为true。这是因为a
和b
是两个list
,所以a[:1] == ['0']
或a[:1] == ['+']
。在每种情况下,它们都与str
不同。
我已将其更改为a[0] != '0' and b[0] != '0'
,可以简化为a[0] != '0' != b[0]
。
使用带有整数键的dict
没有意义,特别是如果这些键是连续的。您只需使用list
。
dict
未被排序,因此values
列表不需要具有与键值对应的顺序。
无需先使用deepcopy
创建新的dict
,然后提取值列表。了解我如何构建values
。
答案 1 :(得分:0)
我玩这个代码并使用之前的答案我找到了一个更快的解决方案:
def sign_to_num(val):
if val == '+':
return 1
elif val == '-':
return -1
return int(val)
def item_sum(left_val, right_val):
return sign_to_num(left_val) + sign_to_num(right_val)
def comp_dict_itself2(d):
values = [list(v) for v in d.values()]
results = {}
for item in values:
key = (" ".join(str(x) for x in item[1:])) #Dict_A_R[]=
if key in results:
results[key][0]= str(item_sum(results[key][0], item[0]))
else:
results[key] = item
DicFinal={}
for pos, item in enumerate(results ):
DicFinal[pos]= results [item]
return DicFinal
前两个函数来自Bakuriu的解决方案新的comp_dict_itself2函数使用创建字典并添加找到的重复次数。
对于我正在运行的词典,这些是个人资料:
ncalls tottime percall cumtime percall filename:lineno(function)
18 58.947 3.275 59.045 3.280 Test_a.py:666(comp_dict_itself)
18 0.193 0.011 0.491 0.027 Test_a.py:675(comp_dict_itself2)