Python3:创建字典的选择性副本作为新字典

Python3:创建字典的选择性副本作为新字典,python,dictionary,python-3.x,copy,Python,Dictionary,Python 3.x,Copy,使用Python 3.3.0,我从csv文件创建了一个“字典”(标题:ID;Col1;Col2;Col3;Col4;Col5): 带代码 file = "test.csv" csv_file = csv.DictReader(open(file, 'r'), delimiter=';', quotechar='"') 我想把ID=12345的行复制到一个新字典中,而不是文件中。 我真的需要把它复制到字典里,而不是列表里,因为我想能够直接对列名进行寻址。 我试着这样做 cewl = {} fo

使用Python 3.3.0,我从csv文件创建了一个“字典”(标题:
ID;Col1;Col2;Col3;Col4;Col5
):

带代码

file = "test.csv" 
csv_file = csv.DictReader(open(file, 'r'), delimiter=';', quotechar='"')
我想把ID=12345的行复制到一个新字典中,而不是文件中。 我真的需要把它复制到字典里,而不是列表里,因为我想能够直接对列名进行寻址。 我试着这样做

cewl = {}
for row in csv_file:
   if row['ID'] == '12345':
   cewl.update(row)
print(cewl)
输出为:

{'ID': '12345', 'Col1': '34', 'Col2': '235', 'Col3': 'dontcare', 'Col4': 'muhaha', 'Col5': 'oldone'}
我的问题: 只有ID=12345的第二行被复制,第一行被省略,我不知道为什么

如果我通过复制到一个新列表(仅用于测试目的)来尝试这一点,则一切正常:

cewl = []
for row in csv_file1:
if row['ID'] == '12345':
    cewl.append(row)
print(cewl)
输出为:

[{'Col3': 'gnrghrtthr', 'Col2': '8', 'Col1': '12', 'Col5': 'latest', 'Col4': 'tznhltrnhklr', 'ID': '12345'}, 
{'Col3': 'dontcare', 'Col2': '235', 'Col1': '34', 'Col5': 'oldone', 'Col4': 'muhaha', 'ID': '12345'}]
我不知道为什么通过复制到新字典中这不起作用……似乎没有像.add或.append这样的dictreader方法


如何将数据复制到新词典中而不丢失任何行?

预期的输出是什么?对于
dict
,这种行为是完全正常的;您将用新值替换每个键的值

如果您希望值是每个匹配行的值列表,则使用带有
列表的
工厂更容易:

from collections import defaultdict

cewl = defaultdict(list)

for row in csv_file:
   if row['ID'] == '12345':
       for k, v in row.items():
           cewl[k].append(v)

print(cewl)
这将产生:

defaultdict(<class 'list'>, {'Col1': ['12', '34'], 'ID': ['12345', '12345'], 'Col2': ['8', '235'], 'Col5': ['latest', 'oldone'], 'Col4': ['tznhltrnhklr', 'muhaha'], 'Col3': ['gnrghrtthr', 'dontcare']})
e、 g.将
cewl
中的每个键设置为正在处理的行中的值。处理最后一行时,其值将覆盖前一行的值

如果只想筛选出与某个
ID
标准匹配的行,那么将它们添加到列表中就完全可以了。然后循环匹配的结果以处理它们:

for row in cewl:
    # do something with matched row
或者,您可以构建一个生成器过滤器,将其环绕在
DictReader()
上,为您进行过滤,这样您就不需要在内存中构建列表:

def rowfilter(reader, id):
    for row in reader:
        if row['ID'] == id:
            yield row

for row in rowfilter(csv_file, '12345'):
    # do something with matched row

@dacoda:python映射对象将一个键映射到一个值。因此
somedict['a']=1
后跟
someddict['a']=2
意味着替换了键
'a'
的值。我建议的解决方案为您提供一个列表值,我们会在找到项目时将其添加到该列表中。不过,我不确定您是否理解python映射的工作原理。如果您需要一个字典列表,请使用您的列表并将行附加到该列表中。@dacoda:我可以很好地阅读您的注释,请不要在注释可用时编辑答案。我想让你给我确切的预期输出,而不是你已经发布的内容(因为“类似于此但不同”的内容不清楚)。:谢谢,我想创建一份字典副本,只包括ID=12345的行,所以在这种情况下,cewl的预期输出应该是标题和两行,每个ID为12345的文件都包含相应的数据。@dacoda:您想做什么?写出一个经过过滤的
csv
文件?
DictReader
为您提供了一系列
dict
对象,就像您的列表输出一样,每一行都有相同的键。你需要更清楚地知道你想做什么,我在这里只是猜测;决定是否要将ID('12345')映射到示例中的两个或多个不同数据段,在这种情况下,可以将ID映射到字典列表,其中包含键
Col1
Col2
等的不同值映射,或者类似元组列表
(ID、Col1、Col2等)
。在编写任何代码之前,先考虑数据结构。
for row in cewl:
    # do something with matched row
def rowfilter(reader, id):
    for row in reader:
        if row['ID'] == id:
            yield row

for row in rowfilter(csv_file, '12345'):
    # do something with matched row