我有一些代码,其中包含字典列表并创建另一个字典列表。列表中的每个字典都有两个键/值对“ ID”和“ opcode”,其中“ opcode”是32位数字。
我的代码需要创建第二个字典列表,其中的操作码是分开的,即,具有opcode = 5的字典将成为具有opcode = 1和opcode = 4的两个字典。
(操作码是32位数字,我的要求是只有1位高,即操作码= 1,2,4,8,16等)
我已将问题简化为以下内容;我的代码需要将此:
part=[{"ID":1,"opcode":4},{"ID":2,"opcode":5},{"ID":3,"opcode":6}]
到这个:
part_=[{"ID":1,"opcode":4},{"ID":2,"opcode":1},{"ID":2,"opcode":4},{"ID":3,"opcode":2},{"ID":3,"opcode":4}]
目前我的代码如下
def bit_set(theNumber,bit):
return theNumber&(1<<bit)!=0
part=[{"ID":1,"opcode":4},{"ID":2,"opcode":5},{"ID":3,"opcode":6}]
part_=[]
for i in part:
for j in range(32):
if bit_set(i["opcode"],j):
part_.append(i)
part_[-1]["opcode"]=(1<<j)
for i in part_:
print(i)
代码的输出为:
{'opcode': 4, 'ID': 1}
{'opcode': 1, 'ID': 2}
{'opcode': 2, 'ID': 3}
有趣的是,如果我稍微修改代码以使值修改行不存在,则会创建额外的字典,但是显然操作码是不正确的。
def bit_set(theNumber,bit):
return theNumber&(1<<bit)!=0
part=[{"ID":1,"opcode":4},{"ID":2,"opcode":5},{"ID":3,"opcode":6}]
part_=[]
for i in part:
for j in range(32):
if bit_set(i["opcode"],j):
part_.append(i)
#part_[-1]["opcode"]=(1<<j)
for i in part_:
print(i)
输出是
{'ID': 1, 'opcode': 4}
{'ID': 2, 'opcode': 5}
{'ID': 2, 'opcode': 5}
{'ID': 3, 'opcode': 6}
{'ID': 3, 'opcode': 6}
我可以通过以不同的方式解决问题来解决问题,但是出于对了解正在发生的事情的兴趣,我超出了深度。
这是因为,当您追加i
到新列表时,您没有创建字典的副本,而是添加了对原始字典的引用。这意味着,当您在下一行更改字典时,也会在中更改值part
。这导致循环不匹配操作码的任何其他部分。如果part
在代码末尾打印出的值,则可以看到此信息。
python文档将其解释为:
Python中的赋值语句不复制对象,它们在目标和对象之间创建绑定。对于可变或包含可变项的集合,有时需要一个副本,因此一个副本可以更改一个副本而无需更改另一个副本。参考
您可以通过在添加字典时创建字典副本来解决此问题。这将使您可以在不影响原始词典的情况下更改值。Python允许您使用copy
模块(文档)复制对象。
只需导入copy
,然后part_.append(copy.copy(i))
代替part_.append(i)
。
import copy
def bit_set(theNumber,bit):
return theNumber&(1<<bit)!=0
part = [{"ID": 1, "opcode": 4}, {"ID": 2, "opcode": 5}, {"ID": 3, "opcode": 6}]
part_=[]
for i in part:
for j in range(32):
if bit_set(i["opcode"],j):
part_.append(copy.copy(i))
part_[-1]["opcode"]=(1<<j)
for i in part_:
print(i)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句