Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 正在尝试从字典列表中的列表中删除特定项。(蟒蛇2)_Python_List_Dictionary - Fatal编程技术网

Python 正在尝试从字典列表中的列表中删除特定项。(蟒蛇2)

Python 正在尝试从字典列表中的列表中删除特定项。(蟒蛇2),python,list,dictionary,Python,List,Dictionary,我的数据结构如下: def cross(A, B): return [a+b for a in A for b in B] digits = '123456789' rows = 'ABCDEFGHI' cols = digits squares = cross(rows, cols) unitlist = ([cross(rows, c) for c in cols] + [cross(r, cols) for r in rows] +

我的数据结构如下:

def cross(A, B):
    return [a+b for a in A for b in B]

digits = '123456789'
rows = 'ABCDEFGHI'
cols = digits
squares = cross(rows, cols)
unitlist = ([cross(rows, c) for c in cols] +
            [cross(r, cols) for r in rows] +
            [cross(rs, cs) for rs in ('ABC', 'DEF', 'GHI') for cs in ('123', '456', '789')])
units = dict((s, [u for u in unitlist if s in u]) for s in squares)
peers = dict((s, set(sum(units[s],[]))-set([s])) for s in squares)
这会导致单位输出

{'A1': [['A1','A2','A3','A4','A5','A6','A7','A8','A9'], 
        ['A1','B1','C1','D1','E1','F1','G1','H1','I1'], 
        ['A1','A2','A3','B1','B2','B3','C1','C2','C3']], 
 'A2': [['A1','A2','A3','A4','A5','A6','A7','A8','A9'],       
        ['A2','B2','C2','D2','E2','F2','G2','H2','I2'], 
        ['A1','A2','A3','B1','B2','B3','C1','C2','C3']],
 'A3': [[etc.]]} 
我希望能够创建单位的副本,但不希望键是它自己列表中的字符串。因此,我希望从前3个列表中删除“A1”A2'从接下来的3个列表中删除,等等

我可以导入副本并执行
units2=copy.deepcopy(units)
然后执行
units2['A1'][0]。删除('A1')
一次执行一个列表。所以我试着做一个循环,一次完成这一切

for s in squares: #assign s to 'A1' then 'A2', etc.
    for x in range(3): #
        units2[s][x].remove(s)
我认为这可以通过跑步完美地完成

units2['A1'][0].remove('A1')
units2['A1'][1].remove('A1')
units2['A1'][2].remove('A1')
units2['A2'][0].remove('A2')
# etc.
不幸的是,在运行此循环后,我的结果是:

units2 = {'B8': [[], [], []], 
          'H1': [[], [], []],
          'C7': [[], [], []],
          'B3': [[], [], []],
          # etc.
          }
因此,不知何故,这个循环正在删除列表中的所有数据,而不仅仅是当前[x]列表中的当前[s]

我尝试过以不同的方式构建列表,甚至制作了81个版本的

for x in range(3):
    units2['A1'][x].remove('A1')
for x in range(3):
    units2['A2'][x].remove('A2')
for x in range(3):
    units2['A3'][x].remove('A3')
但我的字典值都是空的


*我想做的是构建一个数独解算器,然后在PyGame中为游戏生成数独。我计划使用
units2
中的列表来检查是否任何给定列表中只有1个单元格仍然符合特定数字的条件。如果是这种情况,我知道该单元格必须将该数字作为其值,因为它是列、行或9x9块中唯一一个可以根据规则合法保存它的单元格。

使用嵌套列表将单位更改为:

units = dict((s, [[e for e in u if s != e] 
                        for u in unitlist if s in u]) for s in squares)

如果你看看这里发生了什么,然后退一步,答案就显而易见了

毫无疑问,您知道这是什么原因造成的:

In [1]: a = [1,2,3]
In [2]: b = a   
In [3]: a.remove(2)
In [4]: print(a)
[1, 3]

In [5]: print(b)
[1, 3]
这就是为什么您有
copy.deepcopy
。但是,当您查看正在发生的事情时,如果您使用,很明显的答案是您对同一列表有多个引用,并且当您从另一个列表中删除时,最终清空了结构中的所有列表。这里有一个简单的方法来检查:

import collections
import pprint

counter = collections.Counter()
for s in squares:
    for x in range(3):
        counter[id(units2[s][x])] += 1

pprint.pprint(counter)
哪些输出(毫不奇怪):

显然,您的
id
s会有所不同,但计数都是
9

您还可以在循环时使用或检查变量

如果将
单位2
替换为
单位
,则会得到相同的计数。所以这里真正的问题是,为什么不按您认为的方式复制.deepcopy呢?为什么在列表列表中有同一列表的多个副本

让我们尝试一些实验:

list_of_lists = [[1,1,1],
                 [2,2,2],
                 [3,3,3],
                 ]
deepcopy_of_lists = copy.deepcopy(list_of_lists)
print(id(list_of_lists))
print(id(deepcopy_of_lists))
我希望这里有两个不同的id,事实上他们是。但是它们的内容呢

print(id(list_of_lists[0]))
print(id(deepcopy_of_lists[0]))
是的。这些是不同的。如果我们把这些放在字典里呢

dict_of_list_of_lists = {'list_of_lists': list_of_lists}
deepcopy_of_dict = copy.deepcopy(dict_of_list_of_lists)
print(id(dict_of_list_of_lists['list_of_lists'][0]))
print(id(deepcopy_of_dict['list_of_lists'][0]))
我们仍然得到不同的
id
s。一切似乎都在按预期进行,所以很明显我们遗漏了一些东西。哦,是的,我们正在比较复制的列表和原始列表

如果将
单位2
替换为
单位
,则会得到相同的计数

有一个暗示。此外,如果您阅读以下内容:

深度复制操作通常存在两个问题,而浅层复制操作则不存在这两个问题:

  • 递归对象(直接或间接包含自身引用的复合对象)可能导致递归循环
  • 因为深度复制会复制所有内容,所以它可能会复制太多内容,例如,即使在副本之间也应该共享的管理数据结构
deepcopy()函数通过以下方式避免了这些问题:

  • 保存当前复制过程中已复制对象的“备忘录”字典;及
  • 允许用户定义的类重写复制操作或复制的组件集
deepcopy
关注它已经看到的对象

瞧!我们找到了罪魁祸首

在原始词典
units
中,同一列表中有多个不同键的副本。这是因为这一行:

units = dict((s, [u for u in unitlist if s in u]) for s in squares)
本节特别强调:

[u for u in unitlist if s in u]
您在整个词典中重复引用
unitlist
中的列表。幸运的是,这是一个微不足道的修复:

[u[:] for u in unitlist if s in u]
每次都将复制该列表,其余代码将正常工作

import pprint
import copy
import pprint

def cross(A, B):
        return [a+b for a in A for b in B]

digits = '123456789'
rows = 'ABCDEFGHI'
cols = digits
squares = cross(rows, cols)
unitlist = ([cross(rows, c) for c in cols] +
                        [cross(r, cols) for r in rows] +
                        [cross(rs, cs) for rs in ('ABC', 'DEF', 'GHI') for cs in ('123', '456', '789')])

units = dict((s, [u[:] for u in unitlist if s in u]) for s in squares)
peers = dict((s, set(sum(units[s],[]))-set([s])) for s in squares)

units2 = copy.deepcopy(units)
for s in squares: #assign s to 'A1' then 'A2', etc.
    for x in range(3): #
        units2[s][x].remove(s)

pprint.pprint(units2)
产出:

{'A1': [['B1', 'C1', 'D1', 'E1', 'F1', 'G1', 'H1', 'I1'],
        ['A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9'],
        ['A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']],
 'A2': [['B2', 'C2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2'],
        ['A1', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9'],
        ['A1', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']],
 'A3': [['B3', 'C3', 'D3', 'E3', 'F3', 'G3', 'H3', 'I3'],
        ['A1', 'A2', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9'],
        ['A1', 'A2', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']],
 # and so on and so forth
 }

什么是交叉函数?
import pprint
import copy
import pprint

def cross(A, B):
        return [a+b for a in A for b in B]

digits = '123456789'
rows = 'ABCDEFGHI'
cols = digits
squares = cross(rows, cols)
unitlist = ([cross(rows, c) for c in cols] +
                        [cross(r, cols) for r in rows] +
                        [cross(rs, cs) for rs in ('ABC', 'DEF', 'GHI') for cs in ('123', '456', '789')])

units = dict((s, [u[:] for u in unitlist if s in u]) for s in squares)
peers = dict((s, set(sum(units[s],[]))-set([s])) for s in squares)

units2 = copy.deepcopy(units)
for s in squares: #assign s to 'A1' then 'A2', etc.
    for x in range(3): #
        units2[s][x].remove(s)

pprint.pprint(units2)
{'A1': [['B1', 'C1', 'D1', 'E1', 'F1', 'G1', 'H1', 'I1'],
        ['A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9'],
        ['A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']],
 'A2': [['B2', 'C2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2'],
        ['A1', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9'],
        ['A1', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']],
 'A3': [['B3', 'C3', 'D3', 'E3', 'F3', 'G3', 'H3', 'I3'],
        ['A1', 'A2', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9'],
        ['A1', 'A2', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']],
 # and so on and so forth
 }