免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5899 | 回复: 13
打印 上一主题 下一主题

一堆目录名组成的list,如何保留覆盖范围最大的那几个目录 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-01-08 18:02 |只看该作者 |倒序浏览
比如说['/home/tmp2','/home', '/home/tmp1', '/usr', '/usr/bin'] 变成 ['/home', '/usr']
这个列表里面的目录是随机排列的,我如何保留最顶层涵盖范围最大的那几个目录,并且把所有子目录都丢弃?
没有思路,该怎么做?

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
2 [报告]
发表于 2014-01-08 19:40 |只看该作者
如果可以排序:
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-

  3. def main():
  4.     uniq = []
  5.     def comdir(x, y):
  6.         if x and y.startswith(x):
  7.             return x
  8.         else:   
  9.             uniq.append(y)
  10.             return y

  11.     dirs = ['/var/log', '/var/lib',
  12.             '/home/tmp2','/home', '/home/tmp1',
  13.             '/usr', '/usr/bin'
  14.     ]   
  15.     dirs.sort()

  16.     # 排序后的目录名称符合如下规则:如果一组目录能合并为一个目录,
  17.     # 那么该组目录必定连续出现,且该组第一个元素就是那个公共的目录。
  18.     reduce(comdir, dirs, '')

  19.     # 预期结果:['/home', '/usr', '/var/lib', '/var/log']
  20.     print uniq

  21. if __name__ == '__main__':
  22.     main()
复制代码
回复 1# liaozd


   

论坛徽章:
1
子鼠
日期:2014-05-04 13:59:31
3 [报告]
发表于 2014-01-08 20:24 |只看该作者
  1. >>>
  2. >>> import re
  3. >>> a = ['/home/tmp2', '/home', '/home/tmp1', '/usr', '/usr/bin']
  4. >>> for i in a:
  5. ...      b.append(re.findall('/*\w+', i)[0])
  6. ...
  7. >>> list(set(b))
  8. ['/usr', '/home']
复制代码

论坛徽章:
4
白羊座
日期:2013-11-05 10:26:09冥斗士
日期:2015-11-17 14:19:55白银圣斗士
日期:2015-11-17 15:13:0815-16赛季CBA联赛之新疆
日期:2016-04-01 09:10:58
4 [报告]
发表于 2014-01-09 09:45 |只看该作者
本帖最后由 icymirror 于 2014-01-09 14:05 编辑

回复 1# liaozd

思路:
1. 把路径头找出来

  1. rawdata = ['/home/tmp2','/home', '/home/tmp1', '/usr', '/usr/bin'] # 原始数据
  2. newdata = [item[:item.find('/', 1) if item.find('/', 1) > 0 else len(item)] for item in rawdata] # 取出各个原始数据(路径的开头)
复制代码
2. 根据出现的频率来确定是否保留 (不确定需要的 bar ,所以,只统计频率)

  1. import collections
  2. freqdict = collections.defaultdict(int) # 确保如果找不到 key,返回一个整数,0
  3. for item in newdata:
  4.     freqdict[item] += 1
复制代码
3. 频率排序,结果自己过滤

  1. result = [(value, key) for key, value in freqdict.iteritems()]  # 构造一个由元组 (频率, 路径) 组成的列表
  2. result.sort(reverse=True) # 列表排序,从大到小,方便从开头开始取结果
复制代码
Sorry,之前没有改完就回复了,现在是完成之后的内容。

论坛徽章:
5
丑牛
日期:2014-01-21 08:26:26卯兔
日期:2014-03-11 06:37:43天秤座
日期:2014-03-25 08:52:52寅虎
日期:2014-04-19 11:39:48午马
日期:2014-08-06 03:56:58
5 [报告]
发表于 2014-01-09 12:55 |只看该作者
也还是看不懂。
{:2_170:}

论坛徽章:
0
6 [报告]
发表于 2014-01-09 14:36 |只看该作者
回复 2# timespace

谢谢,不过考虑这种情况'/home' 和 '/homeland/'

python是否有判断两个目录是否是互为子目录的模块函数?


   

论坛徽章:
0
7 [报告]
发表于 2014-01-09 16:03 |只看该作者
回复 1# liaozd
  1. def getroot(d):
  2.     ds = d.split("/")
  3.     #print(ds)
  4.     return ds[1]

  5. if __name__ == "__main__":
  6.     dirlist = ['/var/log', '/var/lib',
  7.         '/home/tmp2','/home', '/home/tmp1',
  8.         '/usr', '/usr/bin' ]

  9.     dirdict = dict()
  10.     for d in dirlist:
  11.         rootn = getroot(d)
  12.         dirdict[rootn] = dirdict.get(rootn, 0) + 1

  13.     keys = dirdict.keys()
  14.     for x in keys:
  15.         print(x)

复制代码

论坛徽章:
0
8 [报告]
发表于 2014-01-09 16:45 |只看该作者
本帖最后由 liaozd 于 2014-01-09 16:51 编辑

回复 2# timespace

修改了一下,不知道是不是还有不完备的地方
  1. #!/usr/bin/env python

  2. uniq = []

  3. def comDir(x,y):
  4.         # 所有目录的结尾都加‘/’
  5.         if x is not '' and not x.endswith('/'):
  6.                 x += '/'
  7.         if not y.endswith('/'):
  8.                 y += '/'
  9.         print x, y
  10.         if x and y.startswith(x):
  11.                 return x
  12.         else:
  13.                 uniq.append(y)
  14.                 return y

  15. dirs = ['/var/log', '/var/lib',
  16.         '/home/tmp1','/home', '/home/tmp1/tmp2', ‘/homeland’
  17.         ]

  18. dirs.sort()  

  19. reduce(comDir, dirs, '')

  20. print uniq
复制代码
输出
['/home/', '/homeland/', '/var/lib/', '/var/log/']

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
9 [报告]
发表于 2014-01-09 17:05 |只看该作者
本帖最后由 timespace 于 2014-01-09 17:15 编辑

回复 8# liaozd
哦,明白你意思了,是要让路径名规范化,然后才能准确的用startswith ?

推荐用:
  1. >>> from os.path import normpath
  2. >>> dir1 = ['/usr/lib/', 'usr/../lib', '/usr//lib']
  3. >>> dir2 = [normpath(e) for e in dir1]
  4. >>> dir2
  5. ['/usr/lib', 'lib', '/usr/lib']
复制代码

论坛徽章:
4
金牛座
日期:2013-10-11 16:12:50卯兔
日期:2014-07-31 09:17:19辰龙
日期:2014-08-08 09:28:02狮子座
日期:2014-09-14 20:32:05
10 [报告]
发表于 2014-01-09 18:15 |只看该作者
本帖最后由 ssfjhh 于 2014-01-09 18:18 编辑

一行搞定。
  1. In [1]: a = ['/home/tmp2','/home', '/home/tmp1', '/usr', '/usr/bin']

  2. In [2]: [i for i in a if i.rpartition('/')[0] not in a]
  3. Out[2]: ['/home', '/usr']
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP