Python-按常量列标题排列CSV文件的不同行

Python-按常量列标题排列CSV文件的不同行,python,python-2.7,csv,Python,Python 2.7,Csv,我有一个CSV文件,它会按照以下顺序自动更新一些数据 A,B,C,D,E,F 4,2,6,4,8,9 D,C,A,B,E,F 6,4,5,8,6,2 E,F,A,C,D 4,2,7,6,5 正如您所注意到的,标题值在不同的行中以不同的顺序出现。有时,其中一个标题列值也会丢失 要求使用一致的标题和下面的所有值对其进行排序。例如 A,B,C,D,E,F 4,2,6,4,8,9 A,B,C,D,E,F 5,8,4,6,6,2 A,B,C,D,E,F 7, ,6,5,4,2 或 我尝试用下面的代码对

我有一个CSV文件,它会按照以下顺序自动更新一些数据

A,B,C,D,E,F
4,2,6,4,8,9
D,C,A,B,E,F
6,4,5,8,6,2
E,F,A,C,D
4,2,7,6,5
正如您所注意到的,标题值在不同的行中以不同的顺序出现。有时,其中一个标题列值也会丢失

要求使用一致的标题和下面的所有值对其进行排序。例如

A,B,C,D,E,F
4,2,6,4,8,9
A,B,C,D,E,F
5,8,4,6,6,2
A,B,C,D,E,F
7, ,6,5,4,2

我尝试用下面的代码对它进行排序,但是它只对第一行进行排序,然后按原样打印

with open('mycsv.csv', 'r') as infile, open('reordered.csv', 'a') as outfile:
    fieldnames = ['A','B','C','D','E','F','G']
    writer = csv.DictWriter(outfile, fieldnames=fieldnames)
    writer.writeheader()
    for row in csv.DictReader(infile):
        writer.writerow(row)

任何关于如何实现这一点的建议都会有所帮助。谢谢。

您可以导入您的文件,然后继续读取两行(标题+数据)并为其创建dict。将dict添加到包含所有数据的列表中。 您将获得最大的dict(包含最多键的dict),对其进行排序并将所有数据写回

在缺少键的dict中,可以用空字符串替换其值:

创建数据文件:

with open("t.csv","w") as f:
    f.write("""A,B,C,D,E,F
4,2,6,4,8,9
D,C,A,B,E,F
6,4,5,8,6,2
E,F,A,C,D
4,2,7,6,5""")
然后:

结果文件:

A,B,C,D,E,F
4,2,6,4,8,9
5,8,4,6,6,2
7,,6,5,4,2

我使用python3样式的打印,但是在Python2.7和3.x中代码的工作原理是相同的


确保检查源文件是否包含header+数据行,并且没有空行,否则您必须调整代码以省略空行。

我提出了一个解决方案,其中header可以在任何情况下发挥作用 秩序

这些值被存储到一个字典中,我们需要一个 到目前为止看到的(几)条线

d = {}
count = 0
我们在一对线上有一个循环(这是在
grouper
from, 接下来,我们将这两行用逗号分隔,并创建一个包含 当前标题

for l1, l2 in zip(*[open(datafile)]*2):
    heads = l1.rstrip().split(',')
    vals  = l2.rstrip().split(',') 
    headset = set(heads) 
我们有一个循环来增加与每个字典相关联的列表, 使用
d.setdefault
获得正确的初始值(注意
[None]*0
是无效列表
[]
),如果出现新标题 例如,
计数
为3时,我们将附加到包含3
的列表中,
[无,无,无]

    for h, v in zip(heads, vals): 
        d.setdefault(h,([None]*count)).append(v) 
在考虑了这对中存在的标题之后 对于行,我们考虑了前面看到的标题, 但是你不在这张信用证上

    for h in set(d)-headset:
        d[h].append(None) 
最后我们增加了计数器

    count = count+1           
现在我们准备好输出了,我们对键进行排序,我们打印键 接下来,每两行打印一次列表 与键关联

keys = sorted(d.keys())
print(','.join(keys))
for n in range(count):
    print(','.join(' ' if d[k][n] is None else str(d[k][n]) for k in keys))
全部

d = {}
count = 0
for l1, l2 in zip(*[open(datafile)]*2):
    heads = l1.rstrip().split(',')
    vals  = l2.rstrip().split(',') 
    headset = set(heads) 
    for h, v in zip(heads, vals): 
        d.setdefault(h,([None]*count)).append(v) 
    for h in set(d)-headset:
        d[h].append(None) 
    count = count+1           
keys = sorted(d.keys())
print(','.join(keys))
for n in range(count):
    print(','.join(' ' if d[k][n] is None else str(d[k][n]) for k in keys))
测试它


我尝试过这段代码,但是它在单列中显示的标题很少。@Zoro99 Ooops,我已经在合成数据上测试了我的代码,没有读取文件返回的新行……如果您愿意,可以检查我更新的代码
keys = sorted(d.keys())
print(','.join(keys))
for n in range(count):
    print(','.join(' ' if d[k][n] is None else str(d[k][n]) for k in keys))
d = {}
count = 0
for l1, l2 in zip(*[open(datafile)]*2):
    heads = l1.rstrip().split(',')
    vals  = l2.rstrip().split(',') 
    headset = set(heads) 
    for h, v in zip(heads, vals): 
        d.setdefault(h,([None]*count)).append(v) 
    for h in set(d)-headset:
        d[h].append(None) 
    count = count+1           
keys = sorted(d.keys())
print(','.join(keys))
for n in range(count):
    print(','.join(' ' if d[k][n] is None else str(d[k][n]) for k in keys))
$ cat dat.csv 
A,B,C,D,E,F
4,2,6,4,8,9
D,C,A,B,E,F
6,4,5,8,6,2
E,F,A,C,D
4,2,7,6,5
$ cat head.py 
d = {}
count = 0

for l1, l2 in zip(*[open('dat.csv')]*2):
    heads = l1.rstrip().split(',')
    vals  = l2.rstrip().split(',') 
    headset = set(heads) 
    for h, v in zip(heads, vals): 
        d.setdefault(h,([None]*count)).append(v) 
    for h in set(d)-headset:
        d[h].append(None) 
    count = count+1

keys = sorted(d.keys())
print(','.join(keys))
for n in range(count):
    print(','.join(' ' if d[k][n] is None else str(d[k][n]) for k in keys))
$ python head.py 
A,B,C,D,E,F
4,2,6,4,8,9
5,8,4,6,6,2
7, ,6,5,4,2
$