2015-11-09 67 views
0

感谢百万读者阅读我的文章以及您可能提供的任何信息。将数组写入字典列表

我试图打印到一个CSV文件,并拥有一切工作,直到涉及到打印。我试图打印一个简单的字典列表,并完美的作品,当我输入我的数组名称时,它不会返回一个错误,所以逻辑说我做的是正确的,但是当我试图打印到一个文件时,它只会打印数组列表中的第一项,并将其打印出来3次。我确信我犯了一个愚蠢的错误,但似乎无法在网上找到答案。为了记录,这不是一项家庭作业,这只是我试图自己学习的东西。

import csv 

n = 0 

product = ['Beer', 'Wine', 'Whiskey'] 
item = ['Lager', 'Red', 'Bells'] 
size = ['Pint', 'Bottle', 'Single'] 
price = [5.50, 17.50, 5.50] 


receipt_dict = {'Product': product[n], 
       'Item': item[n], 
       'Size': size[n], 
       'Price': price[n]} 

headings = {'Product', 
      'Item', 
      'Size', 
      'Price'} 

receipt = open('dict.csv', 'w') 
w = csv.DictWriter(receipt, fieldnames=headings, dialect='excel') 
w.writeheader() 

while len(product) != n: 
    w.writerow(receipt_dict) 
    n += 1 

receipt.close() 

如果任何人能够指出我在正确的方向,我会很大。

亲切的问候

马修

+0

要初始化'receipt_dict'与价值观和不改变这些值。即如果在代码开始时n = 1,则产品[n] =='啤酒'。因为您正在迭代n,并不意味着您正在迭代值 –

回答

2

步进通过您的代码,会出现以下情况:

n = 0 

创建一个名为n变量,并将其初始化为0

product = ['Beer', 'Wine', 'Whiskey'] 
item = ['Lager', 'Red', 'Bells'] 
size = ['Pint', 'Bottle', 'Single'] 
price = [5.50, 17.50, 5.50] 

创建一些变量并进行初始化。到现在为止还挺好。 (虽然我会设计不同的数据结构,这还不是一个错误)

receipt_dict = {'Product': product[n], 
       'Item': item[n], 
       'Size': size[n], 
       'Price': price[n]} 

在这里,你创建一个名为receipt_dict变量,并将其初始化到一个新的字典对象。这个表达式在这个时候被评估。由于此时n == 0,这里的值将是每个列表的第一个元素。

也就是说,这与写入下面同样的效果:

receipt_dict = {'Product': 'Beer', 
       'Item': 'Lager', 
       'Size': 'Pint', 
       'Price': 5.50} 

...

while len(product) != n: 
    w.writerow(receipt_dict) 
    n += 1 

由于len(product)3,你的循环将执行三次迭代。每次迭代你写的值为receipt_dict。由于receipt_dict自创建以来未发生更改,并且由于循环不会更改它,因此每次都是相同的。

这就是为什么你会看到同一行三次。

一个解决它的办法就是让一个函数来创建字典:

def create_item(a_number): 
    return {'Product': product[a_number], 
        'Item': item[a_number], 
        'Size': size[a_number], 
        'Price': price[a_number]} 

然后在你的循环,使用功能:

while n < len(product): 
    receipt_dict = create_item(n) 
    w.writerow(receipt_dict) 
    n += 1 

请注意,我在写循环条件更习惯的态度。它甚至会更地道的Python写:

for n in range(len(product)): 
    receipt_dict = create_item(n) 
    w.writerow(receipt_dict) 
+0

您需要将这些列表('product,item,size,price')设置为全局变量来访问它们,对吗? –

+1

@RNar是的,我写这个函数的方式。它们已经是发布的OP脚本中的全局列表。 – dsh

+0

感谢百万@dsh –

1

一个简单的修正涉及移动你的代码依赖于不断变化的n值改变n内循环。如果receipt_dict位于循环内部,它将被重新评估并以您期望的方式进行更改。

另请注意,headings已从一个集合更改为一个列表,因为集合是无序的,因此这些标题将以您无法控制的任意顺序打印出来。当headings是列表时,列的顺序将完全按照您定义的顺序排列。

import csv 

n = 0 

product = ['Beer', 'Wine', 'Whiskey'] 
item = ['Lager', 'Red', 'Bells'] 
size = ['Pint', 'Bottle', 'Single'] 
price = [5.50, 17.50, 5.50] 


headings = ['Product', 
      'Item', 
      'Size', 
      'Price'] 

receipt = open('dict.csv', 'w') 
w = csv.DictWriter(receipt, fieldnames=headings, dialect='excel') 
w.writeheader() 

while len(product) != n: 
    receipt_dict = {'Product': product[n], 
        'Item': item[n], 
        'Size': size[n], 
        'Price': price[n]} 
    w.writerow(receipt_dict) 
    n += 1 

receipt.close() 

一个更Python的方式来编写代码:

import csv 

product = ['Beer', 'Wine', 'Whiskey'] 
item = ['Lager', 'Red', 'Bells'] 
size = ['Pint', 'Bottle', 'Single'] 
price = [5.50, 17.50, 5.50] 

headings = ['Product', 'Item', 'Size', 'Price'] 

with open('dict.csv', 'w') as receipt: 
    writer = csv.writer(receipt, dialect='excel') 
    writer.writerow(headings) 
    for row in zip(product, item, size, price): 
     writer.writerow(row) 

下面我们用一个for循环,而不是一个while循环,我们使用zip来压缩我们的四个名单在一起。我们还使用标题csv.writer而不是DictWriter(这使得代码更简单,因为我们从列表开始而不是字典)。我们还使用with块(上下文管理器)来打开我们的文件,以确保它始终如期关闭,即使发生异常也是如此。

一个可能更加Pythonic的方法是用一个writerows语句替换我们的for循环,传入我们的压缩列表可迭代。

替换此:

for row in zip(product, item, size, price): 
    writer.writerow(row) 

有了这个:

writer.writerows(zip(product, item, size, price)) 
+0

感谢Trey的意见...试图给你一个大拇指,但仍然需要更多的声誉。再次感谢。 –