使用zip或dict函数在Python中将列表转换为字典

使用zip或dict函数在Python中将列表转换为字典,python,dictionary,Python,Dictionary,经过多次尝试,我能够获得下面的代码,为给定的特定csv文件的特定列和行编制索引。现在我想把下面的代码转换成一本字典,我阅读了关于dict和zip的文档,但是我仍然不清楚 CSV文件包含500条记录和对应于以下标题的A:L列: 名字、姓氏、公司、地址、城市、县、州、邮政编码、电话1、电话2、电子邮件、网络 import csv f= open('us-500.csv', 'rU') reader = csv.reader(f) # use list or next ro

经过多次尝试,我能够获得下面的代码,为给定的特定csv文件的特定列和行编制索引。现在我想把下面的代码转换成一本字典,我阅读了关于dict和zip的文档,但是我仍然不清楚

CSV文件包含500条记录和对应于以下标题的A:L列:

名字、姓氏、公司、地址、城市、县、州、邮政编码、电话1、电话2、电子邮件、网络

import csv

f= open('us-500.csv', 'rU')
reader = csv.reader(f)              # use list or next
rows = list(reader)
for row in rows[0:20]:
    print "".join(row[8])

如果您可以将数据分为两个列表(按照您希望的顺序排列),那么您就可以转换为字典了

>>> list_1 = ['pie','farts','boo']
>>>
>>> list_2 = ['apple','stanky','scary']
>>>
>>> dict(zip(list_1,list_2))
{'boo': 'scary', 'farts': 'stanky', 'pie': 'apple'}
>>>
>>> dict(zip(list_2,list_1))
{'apple': 'pie', 'stanky': 'farts', 'scary': 'boo'}
>>>
zip命令有点酷,因为它将两个列表转换为一个列表,其中包含较小的列表

>>> list(zip(list_1,list_2))
[('pie', 'apple'), ('farts', 'stanky'), ('boo', 'scary')]
然后你就把它转换成一个dict

>>> dict(zip(list_1,list_2))
{'boo': 'scary', 'farts': 'stanky', 'pie': 'apple'}

您可以使用
dict
理解

list1  = range(10)
list2 = range(20)
a = {k: v for k, v in zip(list1, list2)}
print a
甚至可以使用
dict()
方法

b = dict(zip(list1, list2))
两种情况下的输出均为:-

{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}

我要胡乱猜一猜你想要什么

你有一个CSV文件,比如说,有10列

您需要一个字典,它使用每行的第8列作为键,整行(即所有列的列表)作为相应的值*

因此,与只提供行列表的
list(reader)
不同,您需要:

d = {row[8]: row for row in reader}
或者,如果您正在使用Python 2.5,并且没有字典理解:

d = dict((row[8], row) for row in reader)
因此,给定此输入文件:

John, Smith, 2, 3, 4, 5, 6, 7, 8, 9, 10
Ed, Jones, 20, 30, 40, 50, 60, 70, 80, 90, 100
你会得到这本字典:

{'8': ['John', 'Smith', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
 '80': ['Ed', 'Jones', '20', '30', 40', '50', '60', '70', '80', '90', '100']}


*这假定第8列的值是唯一的。否则,这就毫无意义了。相反,您可能需要一个multi-dict,将每个column-8值映射到具有该column-8值的所有行的列表,或者一个dict,将每个column-8值映射到一个“multi-row”,将具有该column-8值的每个行的每个列值打包在一起,或者……谁知道呢。一旦你理解了基本想法并知道你想要哪一个,所有这些都很容易写出来。

从你的评论中,听起来你想要的是这样的东西:

  • 行的列表
  • 一个或多个“索引”多指令,将特定列中的值映射到具有该值的一组行号
“多目录”只是将关键字映射到某种集合(如集合或列表)的目录。使用
defaultdict
可以非常轻松地构建一个

您可以使用
enumerate
函数获取每个行号及其值列表

因此,让我们在您的数据上建立两个索引:

import collections
import csv

f= open('us-500.csv', 'rU')
reader = csv.reader(f)              # use list or next
rows = list(reader)

phone1_index = collections.defaultdict(set)
phone2_index = collections.defaultdict(set)
for i, row in enumerate(rows):
    phone1_index[row[8]].add(i)
    phone2_index[row[9]].add(i)
(请注意,这与典型数据库中的索引并不完全相同,它同样适用于查找所有行,其中phone1==?,但对
其中phone1<?
没有帮助)


但实际上,没有理由用指数来思考。如果您只是将行本身存储在dicts中,就不会浪费任何空间;在Python中,可以有两个对同一对象的引用,而不必复制所有数据

有一个小的技术问题,行是列表,因此是可变的,因此不能存储在集合中。但您可能并不希望它们是可变的,它们恰好是这样出现的,所以您可以使用元组来代替:

f= open('us-500.csv', 'rU')
reader = csv.reader(f)              # use list or next
phone1_map = collections.defaultdict(set)
phone2_map = collections.defaultdict(set)
for row in reader:
    row = tuple(row)
    phone1_map[row[8]].add(row)
    phone2_map[row[9]].add(row)

当我们进行此项工作时,这对于
namedtuple
来说似乎是一项不错的工作:

header = 'first_name, last_name, company, address, city, county, state, zip, phone1, phone2, email, web'
Row = collections.namedtuple('Row', header.split(', '))

f= open('us-500.csv', 'rU')
reader = csv.reader(f)              # use list or next
phone1_map = collections.defaultdict(set)
phone2_map = collections.defaultdict(set)
for row in reader:
    row = Row(row)
    phone1_map[row.phone1].add(row)
    phone2_map[row.phone2].add(row)
因此,现在如果您想查找
phone1
phone2
1.555.555.1212
的所有人的姓氏:

matches = phone1_map['1.555.555.1212'] | phone2_map['1.555.555.1212']
names = {match.name for match in matches}
编辑-->根据提问者的评论,我认为这更符合他们的要求(使用DictReader使这更简单):

为主键为第8列“phone1”的文件提供字典。访问这样的值

address_book['555-1212']['first_name'] 
address_book['978-3425']['email'] 

Edit2-->立即删除原始答案。基本上,它是在重新实现DictReader功能。

当你说“转换为字典”时,你希望键和值是什么?而且,你的代码很容易误导。您所称的
列实际上是一个行列表,每个行本身就是一个列列表。所以您要打印前20行中的第8列。而且,由于这已经是一个字符串,
“”.join
只是一种非常低效的方法,无法创建同一字符串的新副本。如果您能给我们几行示例数据和所需的输出,可能会更容易理解您想要的内容。您希望每行一个词典项,还是每列一个词典项?您将处理限制在前20行。这是说明书的一部分吗<代码>列表(读卡器)
读取整个文件,其中可能包含比您想要的更多的行。如果您在输入和预期输出中添加一个片段,它将使您尝试执行的操作更加透明。这将覆盖重复的键-这可能是OP想要的,但值得指出。OP似乎想要前20行,你的代码使用了每一行这真的是对OP想要什么的猜测,我只是希望如果它很接近,它会教会他足够多的东西,能够将它应用到他的实际问题中;我不是想给他代码,他可以直接进入我们看不见的程序,然后用在我们看不见的数据上,然后神奇地得到正确的答案……第8列“phone1”是一个唯一的标识符,前20行是不相关的。在第8列中,我希望将“phone1”的交换部分与中间的3个数字合并或分组。这表明他们生活在同一地理区域或城镇。我使用Pandas Previor来做这件事,但是它将很多思考过程抽象了出来,这就是为什么我想这样做。@user3724235:在解释之后,我仍然不明白你在做什么。同样,请将问题编辑为完整问题,包括输入和所需输出。另外,请看并告诉我我是否猜得更好。如果这是您想要的,只需使用
csv.DictReader
。不熟悉DictReader。你能把我的密码更新到sho吗
address_book['555-1212']['first_name'] 
address_book['978-3425']['email']