python合并word内容相同单元格_python:怎样合并文档中有重复部分的行?

說明一下這個代碼所有的考量.

首先是 順序,這裡的順序有兩個部分,一個是輸出行的順序,一個是項目合併之後的順序.我們觀察到:

pr333 sd23a2 thisisa 1001 1005

pr333 sd23a2 sentence 1001 1005

pr33w sd11aa we 1022 1002

pr33w sd11aa have 1022 1002

pr33w sd11aa adream 1033 1002

要變成:

pr333 sd23a2 thisisa|sentence 1001 1005

pr33w sd11aa we|have|adream 1022|1033 1002

輸出行的順序要顧及: pr333 先於 pr33w

項目合併之後的順序要顧及: thisisa 先於 sentence

這代表我們 使用的資料型態必須要能維持順序

其次是速度,我們都知道序列型態是線性搜尋,為了效率,使用映射型態是比較好的.

三種考量之下,就如同 moling3650 大所言,OrderedDict 是個好選擇.這可以解決行輸出的問題,不過合併項目由於只需要用到 key 而不需要用到 value 所以使用 OrderedDict 有點可惜,不過目前標準庫中沒有 OrderSet 的選擇,所以只好將就著用一下.

有關於 OrderedDict 可以參閱 OrderedDict

最後 linkse7en 大的觀點非常好,這類文檔處理的問題,如果能夠邊讀邊寫,邊讀邊處理絕對是 有效率(因為只需要進行一次文檔的走訪)(討論請見評論部分 moling 大的觀點) 且 省資源(馬上輸出完畢,不必浪費空間儲存資料).但因為考慮到有可能重複的 數據對 有可能跨行出現,所以依然是多花一點資源來確保穩固性.

代碼(Python3):

from collections import OrderedDict

data = OrderedDict()

DPAIR = slice(0,2)

MSG = slice(2,None)

with open('data.txt', 'r') as reader:

for line in reader:

line = line.strip()

items = tuple(line.split())

msgs = data.setdefault(items[DPAIR], [OrderedDict({}) for msg in items[MSG]])

for idx, msg in enumerate(msgs):

msg.setdefault(items[MSG][idx], None)

for (dp1, dp2), msgs in data.items():

print(dp1, dp2, *['|'.join(msg.keys()) for msg in msgs])

關於代碼部分也做個說明(也許我寫的不是最好,但有些心得可以分享).

首先是 slice 類的應用.

身為一個 Python programmer,我們對 序列型態 取切片(slicing) 應該都不陌生.

items[start:stop:step]

其實可以寫成:

items[slice(start, stop, step)]

# example

items[:5] 可以寫成 items[slice(0,5)]

items[7:] 可以寫成 items[slice(7,None)]

那好處是什麼呢?

我們可以利用這個特性對切片進行命名,以這個問題的代碼為例,原本要取出 數據對 與 其他資料 可以用:

items = tuple(line.split())

items[0:2] # 這是用來做 key 的數據對

items[2:] # 這是其他的資料項

但是這種方式其實閱讀起來不夠清晰,我們可以幫這兩個範圍取個名字,所以:

DPAIR = slice(0,2)

MSG = slice(2,None)

items[DPAIR] # 這是用來做 key 的數據對

items[MSG] # 這是其他的資料項

我們可以用比較優雅易讀的方式來從 items 中取值.

其次是 setdefault,這個函數相當實用,舉例:

dic.setdefault(key, default_value)

如果字典(或其他相符的映射型態)中存在鍵值 key 則回傳 dic[key] 否則回傳自動在字典中插入新的鍵值對 dic[key] = default_value 並且回傳 default_value.

最後一個想分享的是嵌套 tuple 的拆解:

for (a, b), c, d in ((1,2) ,3, 4):

print(a, b, c, d) # 印出 1 2 3 4

這個技巧可以很方便的用來拆解巢狀嵌套的 tuple.

感謝大家不嫌我話多...

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值