使用python将csv文件转换为元组列表
Posted
技术标签:
【中文标题】使用python将csv文件转换为元组列表【英文标题】:Converting a csv file into a list of tuples with python 【发布时间】:2013-09-17 13:18:15 【问题描述】:我将获取一个包含 4 列的 csv:品牌、价格、重量和类型。
种类有橙子、苹果、梨子、李子。
参数:我需要选择最可能的重量,但是通过选择 1 个橙子、2 个梨、3 个苹果和 1 个李子,不超过 20 美元的预算。我不能重复同一水果的品牌(例如选择同一品牌的苹果 3 次等)。
我可以通过 Python 打开和读取 csv 文件,但我不确定如何从 csv 文件创建字典或元组列表?
为了更清楚,这里是数据的概念。
Brand, Price, Weight, Type
brand1, 6.05, 3.2, orange
brand2, 8.05, 5.2, orange
brand3, 6.54, 4.2, orange
brand1, 6.05, 3.2, pear
brand2, 7.05, 3.6, pear
brand3, 7.45, 3.9, pear
brand1, 5.45, 2.7, apple
brand2, 6.05, 3.2, apple
brand3, 6.43, 3.5, apple
brand4, 7.05, 3.9, apple
brand1, 8.05, 4.2, plum
brand2, 3.05, 2.2, plum
这就是我现在所拥有的:
import csv
test_file = 'testallpos.csv'
csv_file = csv.DictReader(open(test_file, 'rb'), ["brand"], ["price"], ["weight"], ["type"])
【问题讨论】:
是的,我收到了一些反馈来更改问题的标题和清晰度。这更具体,可以更好地理解问题。 那么请删除旧问题,让他们中的两个关于同一主题毫无意义。另外请发布您的代码到目前为止,这将使人们更有可能帮助您 是的,我前段时间删了,不知道要等一会儿还是不删。网站新手,抱歉! 所有字段名称都需要在一个列表中,例如csv.DictReader(open(test_file, 'rb'), ["brand", "price", "weight", "type"])
。
您的文件是否像您的示例一样有空格?
【参考方案1】:
你可以思考一下:
import csv
def fitem(item):
item=item.strip()
try:
item=float(item)
except ValueError:
pass
return item
with open('/tmp/test.csv', 'r') as csvin:
reader=csv.DictReader(csvin)
data=k.strip():[fitem(v)] for k,v in reader.next().items()
for line in reader:
for k,v in line.items():
k=k.strip()
data[k].append(fitem(v))
print data
打印:
'Price': [6.05, 8.05, 6.54, 6.05, 7.05, 7.45, 5.45, 6.05, 6.43, 7.05, 8.05, 3.05],
'Type': ['orange', 'orange', 'orange', 'pear', 'pear', 'pear', 'apple', 'apple', 'apple', 'apple', 'plum', 'plum'],
'Brand': ['brand1', 'brand2', 'brand3', 'brand1', 'brand2', 'brand3', 'brand1', 'brand2', 'brand3', 'brand4', 'brand1', 'brand2'],
'Weight': [3.2, 5.2, 4.2, 3.2, 3.6, 3.9, 2.7, 3.2, 3.5, 3.9, 4.2, 2.2]
如果您希望 csv 文件逐行作为元组:
import csv
with open('/tmp/test.csv') as f:
data=[tuple(line) for line in csv.reader(f)]
print data
# [('Brand', ' Price', ' Weight', ' Type'), ('brand1', ' 6.05', ' 3.2', ' orange'), ('brand2', ' 8.05', ' 5.2', ' orange'), ('brand3', ' 6.54', ' 4.2', ' orange'), ('brand1', ' 6.05', ' 3.2', ' pear'), ('brand2', ' 7.05', ' 3.6', ' pear'), ('brand3', ' 7.45', ' 3.9', ' pear'), ('brand1', ' 5.45', ' 2.7', ' apple'), ('brand2', ' 6.05', ' 3.2', ' apple'), ('brand3', ' 6.43', ' 3.5', ' apple'), ('brand4', ' 7.05', ' 3.9', ' apple'), ('brand1', ' 8.05', ' 4.2', ' plum'), ('brand2', ' 3.05', ' 2.2', ' plum')]
【讨论】:
你答案的最后一部分正是我想要的。谢谢! ?【参考方案2】:import csv
with open("some.csv") as f:
r = csv.reader(f)
print filter(None,r)
或使用列表理解
import csv
with open("some.csv") as f:
r = csv.reader(f)
print [row for row in r if row]
比较
In [3]: N = 100000
In [4]: the_list = [randint(0,3) for _ in range(N)]
In [5]: %timeit filter(None,the_list)
1000 loops, best of 3: 1.91 ms per loop
In [6]: %timeit [i for i in the_list if i]
100 loops, best of 3: 4.01 ms per loop
[编辑] 因为你的实际输出没有空格,所以你不需要列表理解或过滤器,你可以说list(r)
没有空行的最终答案
import csv
with open("some.csv") as f:
print list(csv.reader(f))
如果你想要听写,你可以做
import csv
with open("some.csv") as f:
reader = list(csv.reader(f))
print [dict(zip(reader[0],x)) for x in reader]
#or
print map(lambda x:dict(zip(reader[0],x)), reader)
【讨论】:
不要做filter(bool, ...)
,使用filter(None, ...)
,filter()
有一个特殊情况可以避免过度转换为bool(因为调用bool的结果也被检查了真实性)。还有,不要做filter(..., list(seq))
,只做filter(..., seq)
,过滤器知道如何迭代序列,中间列表只是浪费空间。
是的,我不确定我对列表转换的想法......我不知道 None 过滤器
不值得使用filter
你可以只使用print [e for e in r]
,它更快、更易读。 -1
请解释一下?那些不是等价的......为什么这是浪费过滤器? (有关 timeit 结果,请参阅编辑)
OP 表示他的 CSV 文件中没有空行。他发错了。如果有空行 - 你会有一点......以上是关于使用python将csv文件转换为元组列表的主要内容,如果未能解决你的问题,请参考以下文章