2015-11-09 66 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的意見...試圖給你一個大拇指,但仍然需要更多的聲譽。再次感謝。 –