<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div>Hi Spyro,<br></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>On Wed, May 29, 2013, at 01:03 AM, Spyro Polymiadis wrote:<br></div>
<blockquote type="cite"><div>Hi folks,&nbsp;<br></div>
<div>&nbsp;</div>
<div>I have a python file querying a database to return a list of paths with output like:<br></div>
<div>&nbsp;</div>
<div>/path/to/folder<br></div>
<div>/path/to/folder/subfolder1<br></div>
<div>/path/to/folder/othersubfolder2<br></div>
<div>/path/to/folder2<br></div>
<div>/path/to/folder/subfolder1<br></div>
<div>/path/to/folder3<br></div>
<div>/path/to/folder4<br></div>
<div>…Etc<br></div>
<div>&nbsp;</div>
<div>which is stored in a variable called 'paths'<br></div>
<div>&nbsp;</div>
<div>How is it possible for me to go through the list – and remove all the entries with "subfolders"<br></div>
<div>And only leave me with the "top level" 'folder' path?<br></div>
</blockquote><div>&nbsp;</div>
<div>&nbsp;</div>
<div>#!/usr/bin/env python<br></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>def remove_subfolders(folders, sep='/'):<br></div>
<div>&nbsp;&nbsp;&nbsp; """Remove folders from that list that are descendants of other folders.<br></div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; Arguments:<br></div>
<div>&nbsp;&nbsp;&nbsp; folders -- List of path strings. E.g. ['/some/folder', '/some/folder2']<br></div>
<div>&nbsp;&nbsp;&nbsp; sep&nbsp;&nbsp;&nbsp;&nbsp; -- Path separator. Default: '/'<br></div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; Return a new list with the descendant folders removed.<br></div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; """<br></div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; folders_set = set(folders)<br></div>
<div>&nbsp;&nbsp;&nbsp; filtered_folders = []<br></div>
<div>&nbsp;&nbsp;&nbsp; for folder in folders:<br></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parts = folder.split(sep)<br></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is_descendant = False<br></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for num_parts in range(1, len(parts)):<br></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sub_path = sep.join(parts[:num_parts])<br></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if sub_path in folders_set:<br></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is_descendant = True<br></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break<br></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not is_descendant:<br></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filtered_folders.append(folder)<br></div>
<div>&nbsp;&nbsp;&nbsp; return filtered_folders<br></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>input_folders = [<br></div>
<div>&nbsp;&nbsp;&nbsp; '/path/to/folder',<br></div>
<div>&nbsp;&nbsp;&nbsp; '/path/to/folder/subfolder1',<br></div>
<div>&nbsp;&nbsp;&nbsp; '/path/to/folder/othersubfolder2',<br></div>
<div>&nbsp;&nbsp;&nbsp; '/path/to/folder2',<br></div>
<div>&nbsp;&nbsp;&nbsp; '/path/to/folder/subfolder1',<br></div>
<div>&nbsp;&nbsp;&nbsp; '/path/to/folder/another/deeper',<br></div>
<div>&nbsp;&nbsp;&nbsp; '/path/to/folder3',<br></div>
<div>&nbsp;&nbsp;&nbsp; '/path/to/folder4',<br></div>
<div>&nbsp;&nbsp;&nbsp; '/path/to/some/folder5',<br></div>
<div>&nbsp;&nbsp;&nbsp; ]<br></div>
<div>&nbsp;</div>
<div>filtered_folders = remove_subfolders(input_folders)<br></div>
<div>print filtered_folders<br></div>
<div>&nbsp;</div>
<div>assert filtered_folders == ['/path/to/folder',<br></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '/path/to/folder2',<br></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '/path/to/folder3',<br></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '/path/to/folder4',<br></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '/path/to/some/folder5']<br></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<blockquote type="cite"><div>&nbsp;</div>
<div>What would be nicer is if there is an option I can add to my select statement in postgres to only return the right folders.<br></div>
</blockquote><div>&nbsp;</div>
<div>&nbsp;</div>
<div>That sounds tough, since the check for each row would depend on every other row, and what it needs to check is variable length (in terms of path components).<br></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<blockquote type="cite"><div>&nbsp;</div>
<div>Any ideas welcome :)<br></div>
</blockquote><div>&nbsp;</div>
<div>&nbsp;</div>
<div>HTH,<br></div>
<div>Tim<br></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<blockquote type="cite"><div>&nbsp;</div>
<div>Cheers<br></div>
<div>Spyro<br></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>--
<br></div>
<div>This message was scanned by ESVA and is believed to be clean.

<br></div>
<div>-- <br></div>
<div>LinuxSA WWW: <a href="http://www.linuxsa.org.au/">http://www.linuxsa.org.au/</a> IRC: #linuxsa on irc.freenode.net<br></div>
<div>To unsubscribe or change your options:<br></div>
<div>&nbsp; <a href="http://www.linuxsa.org.au/mailman/listinfo/linuxsa">http://www.linuxsa.org.au/mailman/listinfo/linuxsa</a><br></div>
</blockquote></body>
</html>