<p>计数器dict不是解决问题的最佳方法,如果要将值与遇到的第一个部分相关联,可以使用以下方法,该方法使用<code>(Value, Package)</code>元组作为键,并将该部分设置为我们遇到的与<code>(Value, Package)</code>对相关联的第一个部分。使用islice是没有意义的,因为您正在拆分前三列,因此没有真正的好处。使用OrderedDict还可以保持文件的顺序:</p>
<pre><code>from collections import OrderedDict
import csv
d = OrderedDict()
with open('test.txt') as f, open("out.csv", "w") as out:
wr = csv.DictWriter(out, fieldnames=["Part", "Value", 'Package', "Amount"])
wr.writeheader()
next(f) # skip header
for line in f:
a, b, c, _ = line.split(None, 3) # split into three columns
key = (b, c) # Value and Package is our key
d.setdefault(key, dict(Amount=0, Part=a, Value=b, Package=c))
d[key]["Amount"] += 1 # increase count every time we see the key
wr.writerows(d.itervalues()) # DictWriter will handle writing the rows
</code></pre>
<p>输出:</p>
<pre><code>Part,Value,Package,Amount
C1,1nF,C0603,1
C2,100nF,C0603,8
C3,10uF_Tantalum,C0603,1
C4,22uF,C0603,1
C5,1uF,C0603,1
C13,0.22uF,C0603,1
C14,2.2uF,C0603,2
HDR_PRGRM_NIET_PLAATSEN,HEADER_1.27_6P,HEADER_1.27_6,1
L1,MURATA10UH,R1210,1
R1,22K,R0603,2
R3,100,R0603,4
R4,483,R0603,1
R10,10k,R0603,1
R11,10K,R0603,2
R14,19.6K,R0603,1
TP1,PTR1TP20R,TP20R,4
TP5,PTR1PAD1-13Y,P1-13Y,2
U$1,WML-C20,WML-C20,1
U$4,MCP4921-E/MS,SOP65P490X110-8N,1
U$6,TSV912DFN8_2X2,DFN8_2X2,1
U$9,LTC3525_BOOST,SC70-6,1
U1,REG71055DDCT,SOT95P180X110-6N,1
U2,ATMEGA32L-8MU,QFN50P700X700X100-45N,1
X1,53047-05,53047-05,1
</code></pre>
<p>如果您想保留所有部分,只需在每个部分后添加计数,则保留与<code>(Value, Package)</code>配对相关联的所有部分的列表,而不只是第一个部分,并编写每个部分、值、包和量,这些部分、值、包和量将在<code>v["Parts"]</code>上迭代,从而保存与特定<code>(Value, Package)</code>相关联的所有部分,为了获得原始顺序上的文件,我们需要使用一个键进行排序,这将是文件中零件出现的行,通过使用dict从我们看到零件的顺序创建映射:</p>
<pre><code>from collections import defaultdict
import csv
d = defaultdict(lambda: dict(Amount=0, Parts=[], Value=b, Package=c))
with open('foo.txt') as f, open("out.csv", "w") as out:
wr = csv.writer(out)
order = {} # use this later to sort
wr.writerow(["Part", "Value", 'Package', "Amount"])
next(f)
for ind, line in enumerate(f):
a, b, c, _ = line.split(None, 3)
order[a] = ind
key = (b, c)
d[key]["Amount"] += 1
d[key]["Parts"].append(a)
# flatten the Parts so we can sort back to the original order
flat = ((k,v["Amount"],v["Value"],v["Package"]) for v in d.itervalues() for k in
v["Parts"])
# sort by part
wr.writerows(sorted(flat, key=lambda x: order[x[0]]))
</code></pre>
<p>输出:</p>
<pre><code>Part,Value,Package,Amount
C1,C0603,1nF,1
C2,C0603,100nF,8
C3,C0603,10uF_Tantalum,1
C4,C0603,22uF,1
C5,C0603,1uF,1
C6,C0603,100nF,8
C7,C0603,100nF,8
C8,C0603,100nF,8
C11,C0603,100nF,8
C12,C0603,100nF,8
C13,C0603,0.22uF,1
C14,C0603,2.2uF,2
C15,C0603,2.2uF,2
C16,C0603,100nF,8
C17,C0603,100nF,8
HDR_PRGRM_NIET_PLAATSEN,HEADER_1.27_6,HEADER_1.27_6P,1
L1,R1210,MURATA10UH,1
R1,R0603,22K,2
R2,R0603,22K,2
R3,R0603,100,4
R4,R0603,483,1
R5,R0603,100,4
R7,R0603,100,4
R10,R0603,10k,1
R11,R0603,10K,2
R12,R0603,100,4
R13,R0603,10K,2
R14,R0603,19.6K,1
TP1,TP20R,PTR1TP20R,4
TP2,TP20R,PTR1TP20R,4
TP3,TP20R,PTR1TP20R,4
TP4,TP20R,PTR1TP20R,4
TP5,P1-13Y,PTR1PAD1-13Y,2
TP6,P1-13Y,PTR1PAD1-13Y,2
U$1,WML-C20,WML-C20,1
U$4,SOP65P490X110-8N,MCP4921-E/MS,1
U$6,DFN8_2X2,TSV912DFN8_2X2,1
U$9,SC70-6,LTC3525_BOOST,1
U1,SOT95P180X110-6N,REG71055DDCT,1
U2,QFN50P700X700X100-45N,ATMEGA32L-8MU,1
X1,53047-05,53047-05,1
</code></pre>
<p>我建议保留上面输出的格式,这样您就可以使用csv模块轻松地再次读取文件。你知道吗</p>
<p>要获得编辑的输出,我们只需将零件更改为列表并添加所有零件:</p>
<pre><code>from collections import OrderedDict
import csv
from itertools import islice
d = OrderedDict()
with open('test.csv') as f, open("out.csv", "w") as out:
_ = list(islice(f, 10)) # skip 10 lines
wr = csv.DictWriter(out, fieldnames=["Parts", "Value", 'Package', "Amount"])
wr.writeheader()
for line in f:
a, b, c, _ = line.split(None, 3) # split into three columns
key = (b, c) # Value and Package is our key
d.setdefault(key, dict(Amount=0, Parts=[], Value=b, Package=c))
d[key]["Amount"] += 1 # increase count every time we see the key
d[key]["Parts"].append(a)
wr.writerows(d.values()) # DictWriter will handle writing the rows
</code></pre>
<p>输出:</p>
<pre><code>Parts,Value,Package,Amount
"['C1', 'C7', 'C10', 'C14', 'C22', 'C25', 'C27']",100n,C0402,7
"['C2', 'C6', 'C8', 'C9', 'C11', 'C12', 'C18', 'C19', 'C20', 'C31', 'C32']",100n,C0603,11
"['C3', 'C4', 'C13', 'C15', 'C28', 'C36']",1u,C0402,6
['C5'],10n-1%,C0402,1
"['C16', 'C33', 'C35', 'C40']",10u,C0402,4
"['C17', 'C24']",22u,C0603,2
"['C21', 'C56', 'C57', 'C58']",100u,A/3216-18R,4
"['C23', 'C26']",10n,C0402,2
['C29'],47uF,C0603,1
['C30'],0.5p,C0402,1
['C34'],120n,C0603,1
"['C34_X5R', 'C34_X5R1']",>2.2u,C0402,2
['C37'],6.8n,C0603,1
['C53'],1u,C0603,1
"['C54', 'C55']",12p,C0603,2
"['D1', 'D2']",PD3S160,POWERDI323,2
['IC1'],OPA333DBV,SOT23-5,1
['J1'],MOLEX_47346-0001,Molex-47346-0001,1
"['L3', 'L4']",BLM15HD182SN1,0402,2
['R1'],33M,R0603,1
"['R2', 'R4', 'R35']",10K,R0402,3
"['R3', 'R8', 'R11', 'R15', 'R19']",2k2,R0402,5
"['R5', 'R6']",10k,R0402,2
"['R7', 'R17', 'R21', 'R36']",10k,R0603,4
['R9'],220,R0603,1
"['R10', 'R12', 'R48', 'R49']",100,R0402,4
"['R13', 'R22']",4.7,R0402,2
"['R14', 'R16']",47,R0402,2
['R18'],15,R0603,1
['R20'],10,R0603,1
['R23'],47k,R0402,1
"['R24', 'R27']",1k,R0402,2
['R28'],20k,R0402,1
['R29'],0.2,R0603,1
['R42'],500,R0603,1
['SOT23-1'],LTC6240,SOT23-5,1
"['T1', 'T5']",PMV16UN,SOT-23,2
"['T2', 'T4', 'T6', 'T8']",FMMT617,SOT-23,4
['T3'],FMMT717,SOT-23,1
['U$1'],BPW34SMD,BPW_34_SMD,1
['U$2'],TPS73433,SOT23-5,1
"['U$4', 'U$5', 'U$6']",LED760/850_ROITHNER,DUOLED_5MM,3
['U$7'],TM4C123GH6ZRBBGA157,BGA_157_MICROSTAR,1
['U$8'],REF3225,SOT95P280X100-6N,1
['U$10'],TPS73633,SOT23-5,1
['U$12'],BNO055LGA-28,LGA-28,1
['U$14'],ECX-42_CRYSTALECS-160-9-42-CKM-TR,ECX-42_CRYSTAL,1
['U$16'],HEADER_1.27_7,HEADER_1.27_7,1
['U1'],ADS8860,SOP50P490X110-10N,1
['U6'],THS4281DBVT,SOT95P280X145-5N,1
</code></pre>