天天好味道

没钱没权没户口,靠走靠吼靠小狗
随笔 - 66, 文章 - 1, 评论 - 524, 引用 - 5

导航

<2006年3月>
2627281234
567891011
12131415161718
19202122232425
2627282930311
2345678

留言簿(12)

随笔分类

随笔档案

文章档案

我的链接

搜索

最新评论

阅读排行榜

评论排行榜

另一个Python和C程序的对比

需求是这样的:
有大量名字以序列号排序 内容如下面内容的文本文件

姓名:aaaa
性别:bbb
年龄:ccc
籍贯:ddd

冒号和内容中间有数量不等的空格,如何能批量导入这些文件进入一个数据库,比如access

形如下面的形式

姓名    性别    年龄    籍贯
aaaa1   bbb1    ccc1    ddd1
aaaa2   bbb2    ccc2    ddd2


其中某项空缺的时候,比如有一个文本文件里年龄空缺,怎么保证列表还能正确






下面是测试用的数据文件: http://dhxy.info/upload/CS/1134036281_1.rar


方案是生成一个csv文件,然后直接导入access,下面是Python实现:
# -*- coding: cp936 -*-
#convert txt data file into csv file
import sys
import os.path

def output(cur):
 s = ""
 keys = ["名字","性别","年龄","籍贯"]
 for key in keys:
  if(cur.has_key(key)):
   s += cur[key]
  s += ","
 s+="\n"
 return s

def convertFile(filename):
 try:
  f = file(filename,'r')
  fout = file("result.csv",'a')
  #fout.writelines("name,sex,age,birthplace\n")
  cur = {}
  s=f.readline()
  tokens = ["名字","性别","年龄","籍贯"]
  
  while len(s) > 0:
   lv = s.split(":",2)
   if(len(lv)!=2):
    s=f.readline()
    continue
   token = lv[0].lower()
   value = lv[1]
   if cur.has_key(token) or len(cur)==len(tokens):
    result = output(cur)
    fout.writelines(result)
    cur = {}
   if token in tokens:
    cur[token] = value.lstrip().rstrip("\n")
   else:
    print "error line"
   s=f.readline()
  if len(cur) > 0:
   result = output(cur)
   fout.writelines(result)
  fout.close();
  f.close()  
 except IOError:
  print "data file not found!"

#main program
if len(sys.argv) != 2:
 print "Usage:python convert.py directory"   
 sys.exit()
  
dirname = sys.argv[1]
try:
 entryList = os.listdir(dirname)
 #remove the result file first and write the header
 fout = file("result.csv",'w+')
 fout.writelines("名字,性别,年龄,籍贯\n")
 fout.close()
 for entry in entryList:
  if os.path.isdir(dirname + "\\" + entry):
   pass
  else:
   convertFile(dirname + "\\" + entry) 
except WindowsError:
 print "Dir not found!" + dirname


测试了一下,发现python干这个效率还不赖,6个数据文件,每个5M,P4 2.8G,大概30s跑完。下面是我的同学实现的C代码(跟上一个例子里同一个人:))
#include <stdio.h>
#include 
<stdlib.h>
#include 
<ctype.h>
#include 
<string.h>

#define OUT_FILE  "result.csv"
#define RECORD_MAX_LEN  256
struct _record {
    
char name[RECORD_MAX_LEN];
    
char sex[RECORD_MAX_LEN];
    
char age[RECORD_MAX_LEN];
    
char birth[RECORD_MAX_LEN];
    
int name_len;
    
int sex_len;
    
int age_len;
    
int birth_len;
}
;
struct _record record;

static char *token[] = {
    
"名字:",
    
"性别:",
    
"年龄:",
    
"籍贯:"
}
;

static inline int out_record(FILE *out)
{   
    
//fprintf(stdout, "%s,%s,%s,%s ", record.name, record.sex, record.age, re
cord.birth);
    fwrite(record.name, 
1, record.name_len, out);
    fwrite(
","11out);
    fwrite(record.sex, 
1, record.sex_len, out);
    fwrite(
","11out);
    fwrite(record.age, 
1, record.age_len, out);
    fwrite(
","11out);
    fwrite(record.birth, 
1, record.birth_len, out);
    fwrite(
" "11out);
    record.name[
0= '

测试结果,比Python快11倍....

所以,Python的速度的确比C要慢得多,这些开销主要来自他的动态类型. 在上一个例子中,体现不明显,
性能就不相上下了.

posted on 2006-03-28 15:31 jzhang 阅读(2665) 评论(9)  编辑 收藏

评论

# re: 另一个Python和C程序的对比

呵,不要被忽悠了,加上
setvbuf(finfile,NULL,_IOFBF,18*1024);
试试。
2006-03-28 15:49 | sevencat

# re: 另一个Python和C程序的对比

你可以把文件给我,我基本可以保证比python要快。
2006-03-28 15:49 | sevencat

# 文件在文章里有链接的

而且我的结论是C比Python快11倍阿。。老兄看错了吧?
2006-03-28 15:52 | jzhang

# re: 另一个Python和C程序的对比

啊,看错了,SORRY
2006-03-28 15:52 | sevencat

# re: 另一个Python和C程序的对比

偶改了你的 #main program 以下 改为
fout = file("result.csv",'w+')
fout.writelines("名字,性别,年龄,籍贯\n")
begin = time.clock()
convertFile("data1.txt")
end = time.clock()
print end - begin

也贴出一个偶滴实现
# -*- coding: cp936 -*-

import time

fout = file("my_result.csv",'w+')
fout.writelines("名字,性别,年龄,籍贯\n")

def write_item (item):
fout.write(item['名字'] + ',');
fout.write(item['性别'] + ',');
fout.write(item['年龄'] + ',');
fout.write(item['籍贯'] + '\n');


def convert(filename):
f = open(filename)
item = {
'名字':'',
'性别':'',
'年龄':'',
'籍贯':''
}
for line in f:
pair = line.split(':')
if len(pair) != 2:
continue
key = pair[0].strip()
value = pair[1].strip()
if key == '名字':
if len(item['名字']) > 0:
write_item(item)
item = {
'名字':'',
'性别':'',
'年龄':'',
'籍贯':''
}
item[key] = value
f.close

begin = time.clock()
convert("data1.txt")
end = time.clock()
fout.close()
print end - begin

在偶滴机器上 输出的结果分别为
5.14033291941

2.68210401043
2006-03-29 10:17 | imjj

# to imjj,不错,速度提高了一倍

赞,这样和C的差距就缩小到5倍了,呵呵
2006-03-29 11:42 | jzhang

# re: 另一个Python和C程序的对比

我猜想速度快的原因主要是写文件之前 省略了把字符串拼起来
的步骤  那个操作会分配新的对象和拷贝内存 消耗比较大的 
OSX 10.3的python不支持gb2312编码 所以我没法测试 :-(
2006-04-02 23:53 | TripleX

# re: 另一个Python和C程序的对比

比较C和Python的速度本身就没什么意义吧?
我最喜欢Python的方面是他的语法,简洁统一,充满美感。
当然性能还过得去,但和C比就没办法了,我想很少人会在这方面苛求吧。
OSX10.3上的Python应该版本不太低吧,Unicode都支持的不错,gb2312应该也可以吧(是不是有gbk呢)?
2007-01-31 17:46 | mirage

# Python很美我倒没感觉

我觉得他最强的是他的库,其次是他进入了.net和S60的世界。这两点其他脚本语言都不能比。
2007-02-01 08:53 | jzhang
标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]