Python 如何从csv中读取多行
我有一个csv文件,其中包括姓名和电话号码。我只对一个名字感兴趣,只要我有它的电话号码Python 如何从csv中读取多行,python,csv,list-comprehension,Python,Csv,List Comprehension,我有一个csv文件,其中包括姓名和电话号码。我只对一个名字感兴趣,只要我有它的电话号码 with open(phone_numbers) as f: reader = csv.DictReader(f) names = [record['Name'] for record in reader if record['phone']] 但我也想要相应的电话号码,我尝试过: user_data = {} with open(phone_numbers) as f: read
with open(phone_numbers) as f:
reader = csv.DictReader(f)
names = [record['Name'] for record in reader if record['phone']]
但我也想要相应的电话号码,我尝试过:
user_data = {}
with open(phone_numbers) as f:
reader = csv.DictReader(f)
user_data['Name'] = [record['Name'] for record in reader if record['phone']]
user_data['phone'] = [record['phone'] for record in reader if record['phone']]
user_data = {}
with open(phone_numbers) as f:
reader = csv.DictReader(f)
user_data['Name'],user_data['phone'] = [(record['Name'],record['phone']) for record in reader if record['phone']]
但是对于第二项,我得到了一个空字符串,我猜record
是一个生成器,这就是为什么我可以迭代它两次
我曾尝试使用元组,但仅以这种方式工作:
user_data = {}
with open(phone_numbers) as f:
reader = csv.DictReader(f)
user_data['Name'] = [(record['Name'],record['phone']) for record in reader if record['phone']]
在这种情况下,我有两个变量,phone
和Name
存储在user\u data['Name']
中,这不是我想要的
如果我试试这个:
user_data = {}
with open(phone_numbers) as f:
reader = csv.DictReader(f)
user_data['Name'] = [record['Name'] for record in reader if record['phone']]
user_data['phone'] = [record['phone'] for record in reader if record['phone']]
user_data = {}
with open(phone_numbers) as f:
reader = csv.DictReader(f)
user_data['Name'],user_data['phone'] = [(record['Name'],record['phone']) for record in reader if record['phone']]
我得到了以下错误:
ValueError:要解压缩的值太多
编辑:
这是表格的一个示例:
+--------+---------------+|电话号码|
+--------+---------------+
|路易斯| 000 111 22222 |
+--------+---------------+
|保罗| 000 222 3333 |
+--------+---------------+
|安德里亚| |
+--------+---------------+
|豪尔赫| 111 222 3333 |
+--------+---------------+
所以所有的行都有一个名字,但不是所有的行都有电话。你猜得很对。如果这是您希望采用的方法-迭代两次,则应使用
seek(0)
但是,这不是很有效,您应该尝试一次性获取数据。以下各项应一次性完成:
user_data = {}
def extract_user(user_data, record):
if record['phone']:
name = record.pop('name')
user_data.update({name: record})
[extract_user(user_data, record) for record in reader]
例如:
In [20]: cat phones.csv
name,phone
hans,01768209213
grettel,
henzel,123457123
In [21]: f = open('phones.csv')
In [22]: reader = csv.DictReader(f)
In [24]: %paste
user_data = {}
def extract_user(user_data, record):
if record['phone']:
name = record.pop('name')
user_data.update({name: record})
[extract_user(user_data, record) for record in reader]
## -- End pasted text --
Out[24]: [None, None, None]
In [25]: user_data
Out[25]: {'hans': {'phone': '01768209213'}, 'henzel': {'phone': '123457123'}}
我认为有一种更简单的方法,因为它是一个csv文件,因为有列标题,如您所示,然后每行中都有一个phone值,它要么是空的,要么是什么-因此此测试不做任何测试,如果不是空的,则将名称和phone添加到用户_数据中
import csv
user_data = []
with open(f,'rb') as fh:
my_reader = csv.DictReader(fh)
for row in my_reader:
if row['phone'] != ''
user_details = dict()
user_details['Name'] = row['Name']
user_details['phone'] = row['phone']
user_data.append(user_details)
通过使用DictReader,我们让魔法发生,所以我们不必担心seek等问题
如果我不懂,而你想要一本字典,那就很容易了
import csv
user_data = dict()
with open(f,'rb') as fh:
my_reader = csv.DictReader(fh)
for row in my_reader:
if row['phone'] != ''
user_data['Name'] = row['phone']
有没有可能您正在寻找的是丢弃数据文件中的一些信息
In [26]: !cat data00.csv
Name,Phone,Address
goofey,,ade
mickey,1212,heaven
tip,3231,earth
In [27]: f = open('data00.csv')
In [28]: r = csv.DictReader(f)
In [29]: lod = [{'Name':rec['Name'], 'Phone':rec['Phone']} for rec in r if rec['Phone']]
In [30]: lod
Out[30]: [{'Name': 'mickey', 'Phone': '1212'}, {'Name': 'tip', 'Phone': '3231'}]
In [31]:
另一方面,如果您的文件只包含Name
和Phone
列,则
只是
您可以使用
dict
将元组列表转换为字典。此外,如果您的记录没有phone
值,则需要使用get
import csv
user_data = {}
with open(phone_numbers) as f:
reader = csv.DictReader(f)
user_data = dict([(record['Name'], record['phone']) for record in reader if record.get('phone').strip())
如果要分别列出name
s和phone
s,可以使用*
表达式
我通常使用行索引:
input = open('mycsv.csv', 'r')
user_data = {}
for row in csv.reader(input):
if row[<row # containing phone>]:
name = row[<row # containing name>]
user_data[name] = row[<row # containing phone>]
input=open('mycsv.csv','r')
用户_数据={}
对于csv.reader中的行(输入):
如果第[]行:
名称=行[]
用户_数据[名称]=行[]
除了打开包装外,您在整个过程中都是正确的
result = [(record["name"], record["phone"]) for record in reader if record["phone"]]
# this gives [(name1, phone1), (name2,phone2),....]
您必须执行
[dostuff for name,phone in result]
而不是name,phone=result
,这在语义和语法上都没有意义 尝试zip(*)
转换最后一行中的列表。检查此答案。您可以澄清您的数据是一列还是多列,如果多列是同一行中的电话号码和姓名吗?我想您是在表明电话和姓名在同一行中row@PyNEwbie它是多列的,所有行都有名称,但不是所有行都有电话号码,这是我在使用if record['phone']时的方式。我不确定这是否是问题所在-最后一个块会重新打开文件。问题在于解包。OP想要一个字典作为最终结果,你的构造将给他一个字典列表谢谢我仍然不清楚,但两个选项都会work@PyNEwbie我尝试了你的第二个密码,我有一个电话号码分配给一个名字,但我想与姓名和电话,如果电话存在。出于某种原因,我只得到一行的值,文件有几行。@Luis得到一行的值可能是因为python dict不支持重复键-最后一行获胜。如果你需要重复的钥匙,这里有可能的解决办法:谢谢,两个都有效。dict方法是否适用于两个以上的项目?它还将第一个值作为键,这意味着如果有重复的值,它将被破坏?@是的,它将适用于两个以上的项目。如果文件中有重复的名称
,则不会中断,但只保留最后一个值。如果您有一个重复的键,我的意思是name
最好的方法是将结果保存为元组的列表。顺便说一句,这就是使用的tuple
。如果答案有帮助,也不要忘记接受。
result = [(record["name"], record["phone"]) for record in reader if record["phone"]]
# this gives [(name1, phone1), (name2,phone2),....]