[英]Updating CSV file (add/remove rows) with Python 3
大家好,
我有一個Raspberry Pi系統,可以跟蹤各種用戶正在檢查的工具。 我進行了設置,以便在用戶簽入時以及簽出時執行系統掃描。 通過比較兩次掃描,我可以確定是否已經采取/返回工具。 但是,我還有一個Log.csv文件,用於跟蹤當前檢出的工具。 我可以在檢出工具時添加到此日志中(這里沒有問題),但是在返回工具時我無法刪除該行。
我搜索過SO以尋求解決方案,但沒有找到任何具體的解決方案。 根據我的理解,您無法從CSV文件中刪除單行? 我將不得不重寫該文件,該特定行被省略?
這是我到目前為止所做的,包括在Log.csv文件中添加和刪除行:
with open('Log.csv', 'a+') as f:
reader = csv.reader(f)
if tools_taken not in reader:
csv.writer(open('Log.csv', 'a+')).writerow([tools_taken])
with open('Log.csv', 'a+') as f:
reader = csv.reader(f)
if tools_returned in reader:
???
請記住,上面的代碼已經過簡化,以保持簡潔。 我認為“如果工具在閱讀器中退回”行太模糊了。 我可能會改為:
for row in reader:
for field in row:
if field == tools_taken:
???
我是在正確的軌道上嗎? 這里的任何輸入將非常感謝!
根據我的理解,您無法從CSV文件中刪除單行? 我將不得不重寫該文件,該特定行被省略?
究竟。 事實上,對於一般的文件來說也是如此。 為了從文件中間刪除東西,你必須向上移動文件的其余部分,然后截斷留下的殘骸。 您通常不想這樣做,因此csv
模塊無法幫助您。
那么,如何創建新的CSV文件? 三種方式:
Log.csv.bak
,在讀取模式下打開,在寫入模式下打開Log.csv
,然后從一個復制到另一個。 Log.csv
,以寫入模式打開臨時文件,從一個復制到另一個,然后將臨時文件原子重命名為Log.csv
。 第三個通常是最好的 - 但不幸的是,很難以跨平台的方式,甚至只是為了Windows。 (但是,如果你只關心Unix,這很容易。)所以,我將展示第二個:
os.rename('Log.csv', 'Log.csv.bak')
with open('Log.csv.bak') as infile, open('Log.csv', 'w') as outfile:
reader = csv.reader(infile)
writer = csv.writer(outfile)
for row in reader:
if not supposed_to_be_removed(row):
writer.writerow(row)
而已。
這類似於編寫復制算法代替簡單列表的變異算法的方式:
newlist = [row for row in oldlist if not supposed_to_be_removed(row)]
當然你可以用迭代器而不是列表來編寫它:
newlist = (row for row in oldlist if not supposed_to_be_removed(row))
事實上,你可以在這里使用完全相同的迭代器:
os.rename('Log.csv', 'Log.csv.bak')
with open('Log.csv.bak') as infile, open('Log.csv', 'w') as outfile:
reader = csv.reader(infile)
writer = csv.writer(outfile)
newrows = (row for row in reader if not_supposed_to_be_removed(row))
writer.writerows(newrows)
如果你願意,你甚至可以把它變成一個單行程:
writer.writerows(row for row in reader if not supposed_to_be_removed(row))
最后,可能值得考慮一下csv
文件是否真的是正確答案。 如果你正在做一大堆操作,不斷重讀和重復寫文件將會很痛苦 - 而且速度很慢。 也許你可以將它保存在內存中,只需讀寫,啟動和關閉,但是你必須確保不丟失錯誤數據。 另見其他選擇。
我不認為csv
在這里是正確的結構。 您希望能夠查找給定的工具,找出其tools_taken
是否為True,或者更改其tools_taken
,或從文件中刪除工具,或者將工具添加到文件中,對吧?
這就是數據庫的用途,例如shelve
:
import contextlib
import shelve
tools = shelve.open('Log.db', 'c', writeback=True)
with contextlib.closing(tools):
# Add a tool
tools['hammer'] = {'name': 'Hammer', 'owner': 'Joe', 'tools_taken': False}
# Check if a tool is taken
if tools['screwdriver']['tools_taken']:
print('The screwdriver is taken!')
# Change a tool's taken status:
tools['screwdriver']['tools_taken'] = True
# Remove a tool
del tools['jackhammer']
換句話說,你可以就像一個dict
(在這種情況下,充滿了dict
),但它在運行中自動持久化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.