【已解决】python脚本应该如何写?在同一个文件里,如果有某一行前两位元素与另一行前两位元素相同的,只保留一行

软件和网站开发以及相关技术探讨
回复
头像
yq-ysy
论坛版主
帖子: 4432
注册时间: 2008-07-19 12:44
来自: 广西(桂)南宁(邕)

【已解决】python脚本应该如何写?在同一个文件里,如果有某一行前两位元素与另一行前两位元素相同的,只保留一行

#1

帖子 yq-ysy » 2018-09-25 23:23

例如,有一个文件 test.txt 内容如下:
01 彐 200
1 一 200
0 即 100
1 一 100
01 寻 100
1 一 300
5 乙 200
5 乙 300
011 建 100
12 十 300
34 十 200
现希望获得的结果如下:(3个一、2个乙、前两位相同,所以都只保留一个。2个十,前两位不同,所以两个都保留。)
01 彐 200
0 即 100
1 一 100
01 寻 100
5 乙 200
011 建 100
12 十 300
34 十 200
即:在同一个文件里,如果有某一行前两位元素与另一行前两位元素相同的,只保留一行(最好是保留第三个元素最小的那一行)。
请问这样的python脚本应该如何写?

更新,已解决,详情见2楼3楼。
头像
astolia
论坛版主
帖子: 6396
注册时间: 2008-09-18 13:11

Re: 【求助】python脚本应该如何写?在同一个文件里,如果有某一行前两位元素与另一行前两位元素相同的,只保留一行

#2

帖子 astolia » 2018-09-26 15:13

没学过python,awk搞起来也很简单
如果输出结果的顺序有没有要求:

代码: 全选

awk '{key=$1" "$2;if(!(key in a)||int(a[key])>int($3)){a[key]=$3}}END{for(key in a){print key,a[key]}}'
如果要求保持最初出现的顺序

代码: 全选

awk 'BEGIN{i=0}{key=$1" "$2;if(!(key in a)){b[i++]=key};if(!(key in a)||int(a[key])>int($3)){a[key]=$3}}END{for(j=0;j<i;j++){print b[j],a[b[j]]}}'
如果要求保持最小值出现的顺序(如你给的示例)

代码: 全选

awk 'BEGIN{i=0}{key=$1" "$2;if(!(key in a)||int(a[key])>int($3)){a[key]=$3;if(key in b){delete c[b[key]]};b[key]=i;c[i]=key;i++}}END{for(j=0;j<=i;j++){if(j in c){print c[j],a[c[j]]}}}'
头像
astolia
论坛版主
帖子: 6396
注册时间: 2008-09-18 13:11

Re: 【求助】python脚本应该如何写?在同一个文件里,如果有某一行前两位元素与另一行前两位元素相同的,只保留一行

#3

帖子 astolia » 2018-09-26 15:19

基本思想就是,dict里以前两段为key存储,遇到没有的直接存,遇到有的比较一下值存较小的。每一行处理完后dict里就是最终无序的结果了,然后用其他方式记录顺序,联合dict输出就是。把上面awk脚本翻译成python3脚本(python2把最后print的括号去掉)就是

代码: 全选

a = {}
b = {}
c = []
i = 0
f = open('/tmp/a.txt', 'r')
for line in f:
    p = line.rstrip('\n').split(' ')
    key = p[0] + ' ' + p[1];
    if ((key not in a) or int(a[key])>int(p[2])):
        a[key] = p[2]
        if (key in b):
            c[b[key]] = None
        b[key] = i
        c.append(key)
        i = i + 1
f.close()
for key in c:
    if key is not None:
        print (key, a[key])
头像
yq-ysy
论坛版主
帖子: 4432
注册时间: 2008-07-19 12:44
来自: 广西(桂)南宁(邕)

Re: 【求助】python脚本应该如何写?在同一个文件里,如果有某一行前两位元素与另一行前两位元素相同的,只保留一行

#4

帖子 yq-ysy » 2018-09-26 20:38

astolia 写了: 2018-09-26 15:19 基本思想就是,dict里以前两段为key存储,遇到没有的直接存,遇到有的比较一下值存较小的。每一行处理完后dict里就是最终无序的结果了,然后用其他方式记录顺序,联合dict输出就是。把上面awk脚本翻译成python3脚本(python2把最后print的括号去掉)就是

代码: 全选

a = {}
b = {}
c = []
i = 0
f = open('/tmp/a.txt', 'r')
for line in f:
    p = line.rstrip('\n').split(' ')
    key = p[0] + ' ' + p[1];
    if ((key not in a) or int(a[key])>int(p[2])):
        a[key] = p[2]
        if (key in b):
            c[b[key]] = None
        b[key] = i
        c.append(key)
        i = i + 1
f.close()
for key in c:
    if key is not None:
        print (key, a[key])
十分感谢!问题解决。
回复