我有这个值来自sql查询到postgresql(我更改了行的颜色以显示firts值是相同的)
**('80255', 'GRN', Decimal('4.00000000000000000000'))**
('80425', 'GRN', Decimal('1.00000000000000000000'))
**('80255', 'BCN', Decimal('1.00000000000000000000'))**
('80425', 'BCN', Decimal('22.0000000000000000'))
**('80255', 'PT', Decimal('2.0000000000000000'))**
('80425', 'PT', Decimal('5.0000000000000000'))
...
我想转换到下一个,转换为csv文件。
80255;4;1;2
80425;1;22;5
对于每个sku(如80425),我想将库存放在每个位置(GRN / BCN / PT)
答案 0 :(得分:1)
当您拥有具有多个值的键时使用的一个好工具是collections.defaultdict
defaultdict
容器为每个新密钥创建一个新对象,当它遇到已存在的密钥时,它就会运行那把钥匙;在这种情况下,操作是列表方法.append()
。
然后您可以使用csv
模块
import csv, collections as co, decimal as dc, itertools as it
fromdb = [('80255', 'GRN', dc.Decimal('4.00000000000000000000'))
,('80425', 'GRN', dc.Decimal('1.00000000000000000000'))
,('80255', 'BCN', dc.Decimal('1.00000000000000000000'))
,('80425', 'BCN', dc.Decimal('22.0000000000000000'))
,('80255', 'PT', dc.Decimal('2.0000000000000000'))
,('80425', 'PT', dc.Decimal('5.0000000000000000'))]
tocsv = co.defaultdict(list)
for i in fromdb:
tocsv[i[0]].append(i[-1])
with open('output.txt','wb') as f:
cw = csv.writer(f,delimiter=';')
for k,v in tocsv.items():
cw.writerow(tuple(it.chain((k,),v)))
答案 1 :(得分:1)
继续@ bernie的好回答,这里有一个包含更多注释的变体,它不依赖于行顺序,并且可以处理缺失的值:
# import collections and abbreviate it as co
import collections as co
import decimal as dc
import csv
fromdb = [('80255', 'GRN', dc.Decimal('4.00000000000000000000'))
,('80425', 'GRN', dc.Decimal('1.00000000000000000000'))
,('80255', 'BCN', dc.Decimal('1.00000000000000000000'))
,('80425', 'BCN', dc.Decimal('22.0000000000000000'))
,('80255', 'PT', dc.Decimal('2.0000000000000000'))
,('80425', 'PT', dc.Decimal('5.0000000000000000'))]
# Build a dictionary that maps values like '80255'
# to a dictionary containing values for GRN, BCN and PT
tocsv = co.defaultdict(lambda:
{'GRN': 0, 'BCN': 0, 'PT': 0} )
for i in fromdb:
# Array index -1 refers to the last element
# For example, set tocsv['80255']['GRN'] to 4.00
tocsv[i[0]][i[1]] = i[-1]
with open('output.txt','wb') as f:
cw = csv.writer(f,delimiter=';')
# items() returns an iterable of key (k) and value (v) pairs
# For key '80255', the value will be {'GRN': 4, 'BCN': 1, 'PT': 2}
for k,v in tocsv.items():
# writerow() takes an array argument, hence the [] square brackets
cw.writerow([k, v['GRN'], v['BCN'], v['PT']])