首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python3:将字典的选择性副本创建为新字典

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

Stack Overflow用户
提问于 2013-02-12 10:24:23
回答 1查看 1K关注 0票数 1

使用Python3.3.0,我从csv文件(头:ID;Col1;Col2;Col3;Col4;Col5)创建了一个“字典”:

代码语言:javascript
运行
复制
ID;Col1;Col2;Col3;Col4;Col5
15345;1;1;nnngngn;vhrhtnz;latest
12345;12;8;gnrghrtthr;tznhltrnhklr;latest
90834;3;4;something;nonsens;latest
12345;34;235;dontcare;muhaha;oldone

有代码

代码语言:javascript
运行
复制
file = "test.csv" 
csv_file = csv.DictReader(open(file, 'r'), delimiter=';', quotechar='"')

我希望将ID = 12345的行复制到新字典中,而不是复制到文件中。我真的很想把它复制到字典中,而不是一个列表中,因为我希望能够直接找到列名。我试过这样做

代码语言:javascript
运行
复制
cewl = {}
for row in csv_file:
   if row['ID'] == '12345':
   cewl.update(row)
print(cewl)

产出如下:

代码语言:javascript
运行
复制
{'ID': '12345', 'Col1': '34', 'Col2': '235', 'Col3': 'dontcare', 'Col4': 'muhaha', 'Col5': 'oldone'}

我的问题:只复制了第二行ID=12345,省略了第一行,我不知道为什么。

如果我尝试将其复制到一个新的列表中(只是为了测试目的),那么一切都很好:

代码语言:javascript
运行
复制
cewl = []
for row in csv_file1:
if row['ID'] == '12345':
    cewl.append(row)
print(cewl)

产出如下:

代码语言:javascript
运行
复制
[{'Col3': 'gnrghrtthr', 'Col2': '8', 'Col1': '12', 'Col5': 'latest', 'Col4': 'tznhltrnhklr', 'ID': '12345'}, 
{'Col3': 'dontcare', 'Col2': '235', 'Col1': '34', 'Col5': 'oldone', 'Col4': 'muhaha', 'ID': '12345'}]

我不知道为什么复制到新的dictionary...there中不起作用,这似乎不是一种像.add或.append这样的dictreader方法。

如何在不遗漏任何行的情况下将数据复制到新字典中?

EN

Stack Overflow用户

回答已采纳

发布于 2013-02-12 10:30:29

预期的产出是多少?对于一个dict来说,这种行为是完全正常的;您正在用一个新值替换每个键的值。

如果您希望值是每个匹配行的值的列表,那么在defaultdict工厂中使用list会更容易:

代码语言:javascript
运行
复制
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)

这一产出如下:

代码语言:javascript
运行
复制
defaultdict(<class 'list'>, {'Col1': ['12', '34'], 'ID': ['12345', '12345'], 'Col2': ['8', '235'], 'Col5': ['latest', 'oldone'], 'Col4': ['tznhltrnhklr', 'muhaha'], 'Col3': ['gnrghrtthr', 'dontcare']})

defaultdictdict的子类,因此print(cewl['Col1'])将打印['12', '34']

当您使用.update()时,可以有效地执行以下操作:

代码语言:javascript
运行
复制
for k, v in row.items():
    cewl[k] = v

例如,将cewl中的每个键设置为正在处理的行中的值。当处理最后一行时,它的值将覆盖前一行的值。

如果您只想筛选出符合特定ID条件的行,那么将它们添加到列表中就很好了。然后遍历匹配的结果来处理它们:

代码语言:javascript
运行
复制
for row in cewl:
    # do something with matched row

或者,您可以构建一个生成器过滤器,在DictReader()周围进行筛选,这样就不需要在内存中构建列表了:

代码语言:javascript
运行
复制
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
票数 2
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14830282

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档