linlu11 的博客

用python来打乱排序后的文件

sunnyflurry
(stranger)
05-10-27 18:40

用python来打乱排序后的文件

我有一个文本文件,里面记录的是排序后的手机号,一行一个
现在要打乱这个排序,不知道用python实现起来是不是很容易?
新学python,大家给个思路:)

flingfly
(stranger)
05-10-27 20:41

Re: 用python来打乱排序后的文件

不知道怎么描述,就自己写了个程序,你可以参考。
大概:
(1)读取原文件到list
(2)取list中随机位置元素写入文件。
#coding:gb2312
import sys
import random
def usage():
print "usage:program srcfilename dstfilename"
global filename
filename = ""
try:
filename = sys.argv[1]
except:
usage()
raise()
#open the phonebook file
f = open(filename, 'r')
phonebook = [];
#read all number from file
for line in f.readlines( ):
phonebook.append(line)
f.close()
#write to file randomly
try:
filename = sys.argv[2]
except:
usage()
raise()
f = open(filename, 'w')
cnt = len(phonebook)
while (cnt > 0):
try:
pos = random.randrange(0, cnt - 1)
except: #if the cnt = 1, then raise the error
pos = 0
print 'pos' , pos
f.write(phonebook[pos])
del phonebook[pos]
cnt = len(phonebook)
f.close()

panhudie
(stranger)
05-10-28 01:08

Re: 用python来打乱排序后的文件

file = 'file.txt'
newfile = 'newfile.txt'
open(newfile, 'w').writelines (list (set (open(file).readlines())))
可以用set来hash里手机号码, 因为hash可以把顺序打乱了.

sunnyflurry
(stranger)
05-10-28 09:17

Re: 用python来打乱排序后的文件

多谢二位指点:)

passworld
(addict)
05-10-28 13:03

Re: 用python来打乱排序后的文件

hash 其实是有序的可以重复的,random 里有一个 shuffle 可以直接做这件事。

flingfly
(stranger)
05-10-28 14:45

Re: 用python来打乱排序后的文件

谢谢,我也知道怎么简洁的做这件事了,谢谢大家!

flingfly
(stranger)
05-10-28 14:55

Re: 用python来打乱排序后的文件

使用set每次生成的文件内容一致。
使用shuffle,每次内容都不一样。
一个问题请问:python里面文件不close没有问题吗?
呵呵,俺是个写C的。
根据上面两位的建议,我讲程序改如下:
#coding:gb2312
import sys
import random
def usage():
print "usage:program srcfilename dstfilename"
global filename
filename = ""
try:
filename = sys.argv[1]
except:
usage()
raise()
#open the phonebook file
f = open(filename, 'r')
phonebook = f.readlines()
print phonebook
f.close()
#write to file randomly
try:
filename = sys.argv[2]
except:
usage()
raise()
f = open(filename, 'w')
random.shuffle(phonebook)
f.writelines(phonebook)
f.close()

sunnyflurry
(stranger)
05-10-28 15:17

Re: 用python来打乱排序后的文件

我用radom方法以后,执行了一上午,程序没执行完,好郁闷,因为文件很大,一共1000万条记录,刚刚取消了,想其他办法,同事说用sorted方法按后4位排序输出也可以
可是我看了sort的说明,半天没明白哪些参数的意义
The sort() method takes optional arguments for controlling the comparisons.
cmp specifies a custom comparison function of two arguments (list items) which should return a negative, zero or positive number depending on whether the first argument is considered smaller than, equal to, or larger than the second argument: "cmp=lambda x,y: cmp(x.lower(), y.lower())"
key specifies a function of one argument that is used to extract a comparison key from each list element: "key=str.lower"
reverse is a boolean value. If set to True, then the list elements are sorted as if each comparison were reversed.
In general, the key and reverse conversion processes are much faster than specifying an equivalent cmp function. This is because cmp is called multiple times for each list element while key and reverse touch each element only once.
哪位能举个例子说明下cmp参数怎么设置?

flingfly
(stranger)
05-10-28 18:03

Re: 用python来打乱排序后的文件

好像不要那么久啊??
我的机器:
XP, intel 2.8G , 1G memory
测试结果:
好像只要30秒左右
//生成测试文件代码 b.y,执行时间:大概30秒
import os
import sys
import time
now = time.time()
t = time.localtime(now)
print "begin time:",t[0], '-', t[1], '-', t[2], " ", t[3],':', t[4], " " ,t[5]
filename = sys.argv[1]
f = open(filename, "w")
for i in range(0, 10000000):
f.write("%11d\n" % i)
now = time.time()
t = time.localtime(now)
print "begin time:",t[0], '-', t[1], '-', t[2], " ", t[3],':', t[4], " ", t[5]
//打乱排序程序执行时间:大概30秒
#coding:gb2312
import sys
import random
import time
def usage():
print "usage:program srcfilename dstfilename"
global filename
filename = ""
try:
filename = sys.argv[1]
except:
usage()
raise()
#open the phonebook file
now = time.time()
t = time.localtime(now)
print "begin time:",t[0], '-', t[1], '-', t[2], " ", t[3],':', t[4], " " ,t[5]
f = open(filename, 'r')
phonebook = f.readlines()
f.close()
#write to file randomly
try:
filename = sys.argv[2]
except:
usage()
raise()
f = open(filename, 'w')
random.shuffle(phonebook)
f.writelines(phonebook)
f.close()
now = time.time()
t = time.localtime(now)
print "begin time:",t[0], '-', t[1], '-', t[2], " ", t[3],':', t[4], " ", t[5]

sunnyflurry
(stranger)
05-10-28 18:37

Re: 用python来打乱排序后的文件

不会吧,1000万行不是1000行,文件就100多M,你的机子这么快就跑完了?

flingfly
(stranger)
05-10-28 20:06

Re: 用python来打乱排序后的文件

是啊,很快的。是1000万啊。

passworld
(addict)
05-10-28 22:39

Re: 用python来打乱排序后的文件

python 里面文件是一个 object ,在收垃圾的时候会自动关闭文件的,所以理论上不用关,但是因为什么时候收垃圾我们是不知道的,所以有需要你可以自己关上,不管怎么说,跟C程序一样,程序执行完后,所有打开的文件系统会自动关闭的。

flingfly
(stranger)
05-10-29 10:02

Re: 用python来打乱排序后的文件

我明白你的意思的。这么说的话,程序运行结束的时候,文件是还没有关闭的,python关闭的时候去关闭这个文件的。
不过这样就带来一个问题,python关闭的时候会不会丢失数据啊。
在C程序里,如果你没有关闭一个文件,程序关闭的时候,os也会帮助你 关闭这个文件的,可是还是丢失了数据。
不过看了python的源代码,我得到了答案:
在os中,操作系统关闭文件的时候,可能不保证把缓冲的数据写入文件。
而在python中,它是保证调用C接口关闭文件的。
源代码如下:
static void
file_dealloc(PyFileObject *f)//如果没有主动关闭文件,当python结束的时候会调用此函数
{
int sts = 0;
if (f->weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *) f);
if (f->f_fp != NULL && f->f_close != NULL) {
Py_BEGIN_ALLOW_THREADS
sts = (*f->f_close)(f->f_fp); //关闭文件
。。。。。。。。。。。
}
static PyObject *
file_close(PyFileObject *f)//如果我们在python中主动关闭的话,会调用此函数
{
int sts = 0;
if (f->f_fp != NULL) {
if (f->f_close != NULL) {
Py_BEGIN_ALLOW_THREADS
errno = 0;
sts = (*f->f_close)(f->f_fp); //关闭文件
。。。。。。。。。。。。。。。
}

passworld
(addict)
05-10-29 11:40

Re: 用python来打乱排序后的文件

在 C 程序里系统也应该会 flush 然后才关闭的。

flingfly
(stranger)
05-10-29 11:46

Re: 用python来打乱排序后的文件

那为什么如果C里面不关闭一个文件,缓冲的数据会丢失那?

passworld
(addict)
05-10-29 12:43

Re: 用python来打乱排序后的文件

不知道,至少在 linux 上退出是会呼叫 exit(3) 的(__libc_start_main)。应该是 posix吧?

posted on 2009-12-16 22:36  linlu11  阅读(3017)  评论(0编辑  收藏  举报

导航