找回密码
 注册
Simdroid-非首页
查看: 526|回复: 16

[二次开发] Python 小练习之二

[复制链接]
发表于 2011-10-3 06:38:53 | 显示全部楼层 |阅读模式 来自 美国
本帖最后由 Hansha 于 2011-10-2 21:41 编辑

Python小练习之一得到几位网友的支持,谨在此表示感谢。现将大家的程序贴出来,互相学习一下,赋值语句和打印语句都略去了。

这是我的:
c = a
d = []
a.sort()
for i in a:
    p = c.find(i)
    d.append(b[p])
像我这样刚学Python的人来说,也就能写出这样的水平了。将a排序后,它某个元素的原来位置还是在c中,找到这个位置,就找到了对应的b中的元素,中规中矩,还有个缺点,如果a中有重复元素就不好办了。

t=zip(a,b)
t.sort()
a,b=zip(*t)
利用zip,很简练,打包以后排序,再解包,a中有重复元素也没关系。zip里的参数前面加*表示unzip。

for i in range(len(a)-1):
     for n in range(len(a)-1):
          if a[n]>a[n+1]:
              a[n],a[n+1]=a[n+1],a[n]
              b[n],b[n+1]=b[n+1],b[n]
这是自己来sort。有的语言是没sort的,就只有自己干了。缺点是一旦list里的元素多了,循环量很大,对两个各有N个元素的list,就要循环N x N次。

def sort_point (a, b):
        temp_point_list = []
        for i in range(len(a)):
                temp_point_list.append((a,b))
        temp_point_list.sort()
        return temp_point_list
#
if __name__ == '__main__':
        print sort_point(a,b)
这是自己来zip,这种自己动手的精神都是要鼓励的,也是一种锻炼。自己动手也是有回报的。这个速度最快!

cc = dict(zip(a,b))
aa = sorted(a)
bb = [cc[key] for key in aa]
zip后再做成字典,然后用sorted() 函数,看上去比没有做成字典的zip多了一步,可实际上却要快一些。不知是否涉及到内部的算法。

aa,bb=zip(*sorted(zip(a,b),key=lambda d:d[0]))
就一句,牛不牛?这位仁兄对Python应该已到了相当的水平了。我对那个lambda还不知道,有空要看看。

好,下面是第二个练习。

我们都知道,字串有个函数find(),可以找出字串中的子字串。但它有个缺点,只能找一个,最前边的那个,后面再有,就一律不管了。现在要求做一个函数,从字串a中找出所有的子字串b,返回一个list,其中第一个数是子字串b在字串a中的个数,然后是子字串b的首元素的各个位置,譬如有如下两个字串:

a='vavafjioajovmfjofjnjijiogjvamcvmkri'
b='ji'

就应该返回 [3, 5,19,21],表示a中一个有三个b,其首元素‘j’的位置分别为5,19 和21。


点评

等回家了试试,先支持一下  发表于 2011-10-5 11:16

评分

1

查看全部评分

发表于 2011-10-3 07:44:06 | 显示全部楼层 来自 澳大利亚
Simdroid开发平台
也想学学了

点评

好啊,挺有意思滴。  发表于 2011-10-4 11:08
回复 不支持

使用道具 举报

发表于 2011-10-3 09:54:19 | 显示全部楼层 来自 重庆
哈哈,研究这个基本上是google原来干的工作。这回这个题目应该有看头。

点评

看你呢,怎么还不出手啊?  发表于 2011-10-4 11:09
回复 不支持

使用道具 举报

发表于 2011-10-3 12:52:35 | 显示全部楼层 来自 天津
随便写了个,已经发给版主了,可能会存在些问题,版主多提宝贵意见!

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2011-10-4 10:59:49 | 显示全部楼层 来自 美国
凑个热闹。这个系列改为“跟着Hansha学Python”好了

点评

版大别误会,我本意是,真觉得这系列很好,能有个人带着大家一起学效率会高很多:)  发表于 2011-10-5 03:31
rocky兄休得取笑,你是想叫我汗颜是不是?  发表于 2011-10-4 11:06

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2011-10-4 17:58:36 | 显示全部楼层 来自 重庆
这几天老爹来了没空做,刚做了个发给版主了,请查收。

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2011-10-4 21:49:10 | 显示全部楼层 来自 大连理工大学
本帖最后由 huxw 于 2011-10-5 09:16 编辑

有两个问题不明白,还想请教楼主:
1. 对方法一,find函数只能应用于字符串,生成的列表a,b是否应该为字符串列表才能运行?  且要求元素不能重复。
2. 对方法四,LZ说此方法最快,但我觉得有两个疑问:
   (1)temp_point_list.append((a,b)) 是否应该为 temp_point_list.append((a[i], b[i]))? 是对元素的引用,否则得不到预期结果。
   (2)此程序是重编zip()函数,那么要想得到结果,是否还应加一句aa,bb = zip(*temp_point_list),来unzip结果。
详细见下面的代码方法4。为了方便比较学习,将各种方法放在一起,去掉相应方法的注释符号即可运行:
  1. #!/user/bin/python
  2. # -* - coding:UTF-8 -*-
  3. import random, time, string
  4. num=1000000; limits=50000000  ## 可以减小数值,以便验证正确性
  5. a=[]; b=[]; ni=5
  6. for i in range(num):
  7.     a.append(random.randint(0,limits))
  8.     b.append(random.randint(0,limits))
  9. #print a,'\n',b  # 取消行首注释,打印输入列表
  10. print 'Start Method %s'%ni
  11. time_0 = time.clock()
  12. ###################################自编程序  开始#####################################
  13. ##################### 方法 1:不能运行!对list不适用,应该转化成string? 且存在重复时出错。
  14. #c = a
  15. #d = []
  16. #a.sort()
  17. #for i in a:
  18. #    p = c.find(i)
  19. #    d.append(b[p])
  20. #aa,bb = a,d
  21. #
  22. ##################### 方法 2:比较慢,数据量大时 不建议采用
  23. #for i in range(len(a)-1):
  24. #    for n in range(len(a)-1):
  25. #        if a[n]>a[n+1]:
  26. #            a[n],a[n+1]=a[n+1],a[n]
  27. #            b[n],b[n+1]=b[n+1],b[n]
  28. #aa,bb = a,b
  29. #
  30. ##################### 方法 3:
  31. #t = zip(a,b)
  32. #t.sort()
  33. #aa,bb = zip(*t)
  34. #
  35. ##################### 方法 4:
  36. #temp_point_list = []
  37. #for i in range(len(a)):
  38. #    temp_point_list.append((a[i],b[i]))  ## 引用元素,而不是整个列表。加上[i]
  39. #temp_point_list.sort()
  40. #aa,bb = zip(*temp_point_list)    ## 应该缺少这一句
  41. #
  42. ##################### 方法 5:
  43. cc = dict(zip(a,b))
  44. aa = sorted(a)
  45. bb = [cc[key] for key in aa]

  46. ##################### 方法 6:
  47. #aa,bb = zip(*sorted(zip(a,b),key=lambda d:d[0]))
  48. ###################################自编程序  结束#####################################
  49. time_1 = time.clock()
  50. print 'Done'
  51. #print aa,'\n',bb  # 取消行首注释,打印排序结果
  52. print "Method %s: time = %s"%(ni ,time_1 - time_0)
复制代码
利用上面的代码,对各方法分别运行,我这里方法5是最快的。大家试试看。通过大家的方法,学到了不少,非常感谢!

BTW,这次的练习已经发送楼主,可能写得太繁琐了。

点评

终于明白了,[i]在帖子里是斜体的起始标识,怪不得每次都看不到a[i]b[i]。改成全角就好了。  发表于 2011-10-5 09:19

评分

2

查看全部评分

回复 不支持

使用道具 举报

发表于 2011-10-4 22:39:52 | 显示全部楼层 来自 重庆
汗,我摆乌龙了。

点评

摆乌龙了?我算了,能行啊?  发表于 2011-10-5 09:55
没啥呀,我们都在学习  发表于 2011-10-5 08:52

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2011-10-5 08:54:53 | 显示全部楼层 来自 江苏
huxw 发表于 2011-10-4 21:49
有两个问题不明白,还想请教楼主:
1. 对方法一,find函数只能应用于字符串,生成的列表a,b是否应该为字符 ...

这个运行结果可能与电脑也有些关系,前面有人运行也得到了不同结果
回复 不支持

使用道具 举报

发表于 2011-10-5 09:01:00 | 显示全部楼层 来自 大连理工大学
JingheSu 发表于 2011-10-5 08:54
这个运行结果可能与电脑也有些关系,前面有人运行也得到了不同结果

原来是这样,可能是版本不同?
我用的abaqus 6.10自带的python,应该是2.6.2。

点评

我原来装的是2.7。现在改成2.6了,真还不行了。  发表于 2011-10-5 09:57
回复 不支持

使用道具 举报

发表于 2011-10-6 20:15:27 | 显示全部楼层 来自 广东广州
学习了。写得也比较繁琐,继续期待总结。有个问题:’jkjkj'查找'jkj'结果是算两次呢,还是算一次?我当是两次编的程。

点评

我也有此疑问,但我是理解为一次。我是找到一次就直接吧这个单词跨过去了。  发表于 2011-10-6 21:22

评分

1

查看全部评分

回复 不支持

使用道具 举报

 楼主| 发表于 2011-10-8 09:13:18 | 显示全部楼层 来自 美国
clsb1988 发表于 2011-10-6 07:15
学习了。写得也比较繁琐,继续期待总结。有个问题:’jkjkj'查找'jkj'结果是算两次呢,还是算一次?我当是 ...

mlmyf的理解正确,是我没说清楚。其实可以做的更复杂一点,同时给个数n,1<= n <= 子串b的长度,查到一个子串b后,由子串b的首字符在字串a的位置起,去掉字串a的n个字符再接着查。
回复 不支持

使用道具 举报

发表于 2011-10-8 11:09:03 | 显示全部楼层 来自 上海
偷个懒,用了两个python内置的函数

点评

怎么是偷懒呢?这表明对Python掌握的更全面。学习了!  发表于 2011-10-8 11:14

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2011-10-10 23:27:10 | 显示全部楼层 来自 广东惠州
同上 偷个懒,用了3个python内置的函数
回复 不支持

使用道具 举报

发表于 2011-10-11 00:28:06 | 显示全部楼层 来自 广东惠州
本帖最后由 gocadcam 于 2011-10-11 00:50 编辑

对7#的源码稍加修改,以下是某次运行结果
Start Method 3
Done
Method 3: time = 22.2053406499
Start Method 4
Done
Method 4: time = 29.6418087241
Start Method 5
Done
Method 5: time = 11.1714019791
Start Method 6
Done
Method 6: time = 31.4402394812

源码修改如下:
import random, time
## 方法 1:不能运行!对list不适用,应该转化成string 且存在重复时出错。
def mySort1( a, b ):
    c = a
    d = []
    a.sort()
    for i in a:
        p = c.find(i)
        d.append(b[p])
    aa,bb = a,d
    return aa,bb

## 方法 2:冒泡排序 比较慢,数据量大时 不建议采用
def mySort2( a, b ):
    for i in range(len(a)-1):
        for n in range(len(a)-1):
            if a[n]>a[n+1]:
                a[n],a[n+1]=a[n+1],a[n]
                b[n],b[n+1]=b[n+1],b[n]
    aa,bb = a,b
    return aa,bb

## 方法 3:
def mySort3( a, b ):
    t = zip(a,b)
    t.sort()
    aa,bb = zip(*t)
    return aa,bb

## 方法 4:
def mySort4( a, b ):
    temp_point_list = []
    for i in range(len(a)):
        temp_point_list.append((a,b))  ## 引用元素,而不是整个列表。
    temp_point_list.sort()
    aa,bb = zip(*temp_point_list)    ## 应该缺少这一句
    return aa,bb

## 方法 5:
def mySort5( a, b ):
    cc = dict(zip(a,b))
    aa = sorted(a)
    bb = [cc[key] for key in aa]
    return aa,bb

## 方法 6:
def mySort6( a, b ):
    aa,bb = zip(*sorted(zip(a,b),key=lambda d:d[0]))
    return aa,bb


num=1000000; limits=50000000  ## 可以减小数值,以便验证正确性
a=[]; b=[]; ni=5
for i in range(num):
    a.append(random.randint(0,limits))
    b.append(random.randint(0,limits))
    #print a,'\n',b  # 取消行首注释,打印输入列表


mySortList = [ mySort1, mySort2, mySort3, mySort4, mySort5, mySort6 ]
# Only test the Method 3 - 6
for mi in range( 2, 6 ) :
    at = a[:]
    bt = b[:]
    print 'Start Method %d' % (mi+1)
    time_0 = time.clock()
    aa,bb = mySortList[mi]( at, bt )
    time_1 = time.clock()
    print 'Done'
    #print aa,'\n',bb  # 取消行首注释,打印排序结果
    print "Method %d: time = %s"%(mi+1 ,time_1 - time_0)

排序结果的正确性未做验证

方法2 冒泡排序 运行在1小时以上,未做完成测试

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2011-10-11 19:10:46 | 显示全部楼层 来自 福建厦门
本帖最后由 gocadcam 于 2011-10-11 20:21 编辑

今天又仔细看了一下代码,发现LZ与15#的方法4代码有误(本意是验证各方法的排序结果的正确性),7#的是正确的。
同时,经验证,方法5运用set进行排序,虽然速度快,但当a中有重复项时,得到的结果是错误的。
方法 3,4,6都是运用内建的List排序方法sort()对zip序列进行排序。属于同一方法。其中,以方法3的思路清晰,代码简洁,运行速度快。
以下是某次运行结果,仅供参考:

a=[9, 2, 12, 6, 4, 12, 6, 25, 6]
b=[1, 2,  3,  4, 5,  6, 7,  8, 4]
Start Method 2
[2, 4, 6, 6, 6, 9, 12, 12, 25]
[2, 5, 4, 7, 4, 1, 3, 6, 8]
Start Method 3
(2, 4, 6, 6, 6, 9, 12, 12, 25)
(2, 5, 4, 4, 7, 1, 3, 6, 8)
Start Method 4
(2, 4, 6, 6, 6, 9, 12, 12, 25)
(2, 5, 4, 4, 7, 1, 3, 6, 8)
Start Method 5
[2, 4, 6, 6, 6, 9, 12, 12, 25]
[2, 5, 4, 4, 4, 1, 6, 6, 8] #注意结果出错
Start Method 6
(2, 4, 6, 6, 6, 9, 12, 12, 25)
(2, 5, 4, 7, 4, 1, 3, 6, 8)

各方法的排序结果的速度
Start Method 3
Done
Method 3: time = 23.7781405513
Start Method 4
Done
Method 4: time = 30.7797904265
Start Method 5
Done
Method 5: time = 12.135676426   排序结果的正确性待议
Start Method 6
Done
Method 6: time = 33.2384716898


以下是测试代码:

# myTestSort.py
import random, time
## 方法 1:不能运行!对list不适用,应该转化成string 且存在重复时出错。
def mySort1( a, b ):
    c = a
    d = []
    a.sort()
    for i in a:
        p = c.find(i) ## error c is not string object
        d.append(b[p])
    aa,bb = a,d
    return aa,bb

## 方法 2:比较慢,数据量大时 不建议采用
def mySort2( a, b ):
    n = len(a)-1
    for i in range(n):
        for j in range(n):
            if a[j]>a[j+1]:
                a[j],a[j+1]=a[j+1],a[j]
                b[j],b[j+1]=b[j+1],b[j]
    aa,bb = a,b
    return aa,bb

## 方法 3:
def mySort3( a, b ):
    t = zip(a,b)
    t.sort()
    aa,bb = zip(*t)
    return aa,bb

## 方法 4:
def mySort4( a, b ):
    temp_point_list = []
    n = len(a)
    for ii in range(n):
        temp_point_list.append( ( a[ii], b[ii] ) )  ## 引用元素,而不是整个列表。temp_point_list.append( ( a[ii], b[ii] ) )
    temp_point_list.sort()
    aa,bb = zip(*temp_point_list)    ## 应该缺少这一句
    return aa,bb

## 方法 5:
def mySort5( a, b ):
    cc = dict(zip(a,b))
    aa = sorted(a)
    bb = [cc[key] for key in aa]
    return aa,bb

## 方法 6:
def mySort6( a, b ):
    aa,bb = zip(*sorted(zip(a,b),key=lambda d:d[0]))
    return aa,bb


## 以下是测试代码,验证各方法的排序结果的正确性
ta = [ 9, 2, 12, 6, 4, 12, 6, 25, 6 ]
tb = [ 1, 2,  3, 4, 5,  6, 7,  8, 4 ]
mySortList = [ mySort1, mySort2, mySort3, mySort4, mySort5, mySort6 ]
print ta,'\n', tb
for mi in range( 1, 6 ) :
    at = ta[:]
    bt = tb[:]
    print 'Start Method %d' % (mi+1)
    aa,bb = mySortList[mi]( at, bt )
    print aa,'\n',bb  # 取消行首注释,打印排序结果

## 以下是测试代码,测试各方法的排序结果的速度
num=1000000; limits=50000000  ## 可以减小数值,以便验证正确性
a=[]; b=[];
for i in range(num):
    a.append(random.randint(0,limits))
    b.append(random.randint(0,limits))
    #print a,'\n',b  # 取消行首注释,打印输入列表
#mySortList = [ mySort1, mySort2, mySort3, mySort4, mySort5, mySort6 ]
# Only test the Method 3 - 6
for mi in range( 2, 6 ) :
    at = a[:]
    bt = b[:]
    print 'Start Method %d' % (mi+1)
    time_0 = time.clock()
    aa,bb = mySortList[mi]( at, bt )
    time_1 = time.clock()
    print 'Done'
    #print aa,'\n',bb  # 取消行首注释,打印排序结果
    print "Method %d: time = %s"%(mi+1 ,time_1 - time_0)


方法4的代码直接粘贴,a,b列表的下标[ i ]消失同时字体变为斜体,改成a,b [ii]就正常了

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2011-10-11 23:58:59 | 显示全部楼层 来自 大连理工大学
存在重复时,方法5确实结果有误。赞楼上认真仔细!
回复 不支持

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|小黑屋|联系我们|仿真互动网 ( 京ICP备15048925号-7 )

GMT+8, 2024-3-28 21:01 , Processed in 0.070143 second(s), 27 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表