Reputation: 2047
I have a list with some file names(locations), what I am trying to do is I want to remove every elements from the list locations.
Condition: do not print the file name if it starts with the any of the strings in the excludes list.
locations = ['/data/mybackup/data/fil1',
'/data/mybackup/data/fil2',
'/data/mybackup/data/fil3',
'/data/mybackup/song/fil1',
'/data/mybackup/song/fil2',
'/data/mybackup/song/fil3',
'/data/archive/song/fil1',
'/data/archive/song/fil2',
'/data/archive/song/fil3',
'/data/archive/data/fil1',
'/local/archive/data/fil2',
'/local/archive/data/fil3',
'/ebboks/wordpress/fil1',
'/ebooks/wordpress/fil2',
'/ebooks/wordpress/fil3']
excludes = [ '/data/archive/', '/data' , '/ebooks/' ]
for location in locations:
for exclude in excludes:
if not location.startswith(exclude):
print(location)
break
RESULT:
/data/mybackup/data/fil1
/data/mybackup/data/fil2
/data/mybackup/data/fil3
/data/mybackup/song/fil1
/data/mybackup/song/fil2
/data/mybackup/song/fil3
/local/archive/data/fil2
/local/archive/data/fil3
/ebboks/wordpress/fil1
/ebooks/wordpress/fil2
/ebooks/wordpress/fil3
My result still have the file names starting with '/data'
What is wrong with my code?
Upvotes: 2
Views: 99
Reputation: 22093
try list comprehensions:
>>> [location for location in locations \
if not location.startswith(tuple(excludes))]
output:
['/local/archive/data/fil2', '/local/archive/data/fil3', '/ebboks/wordpress/fil1']
or filter
with lambdas if you prefer functional programming in answer of @mshsayem
Upvotes: 0
Reputation: 18008
Because you are checking against /data/archive/
first; it is letting all entries which are not starting with /data/archive/
essentially skipping the check for /data
.
You can do this:
>>> excludes = tuple(excludes)
>>> filter(lambda x: not x.startswith(excludes), locations)
['/local/archive/data/fil2', '/local/archive/data/fil3', '/ebboks/wordpress/fil1']
Upvotes: 1
Reputation: 142156
str.startswith
accepts a tuple
of arguments to check against so you avoid an additional loop to check and concerns about ordering comparisons, so you can use:
exc = tuple(excludes)
# Or start with: excludes = ('/data/archive/', '/data' , '/ebooks/') instead
for location in locations:
if not location.startswith(exc):
print(location)
Which gives you:
/local/archive/data/fil2
/local/archive/data/fil3
/ebboks/wordpress/fil1
Upvotes: 3
Reputation: 92854
Condition: do not print the file name if it starts with the any of the strings in the excludes list.
With all()
function:
for location in locations:
if all(not location.startswith(e) for e in excludes):
print(location)
The output:
/local/archive/data/fil2
/local/archive/data/fil3
/ebboks/wordpress/fil1
Upvotes: 3
Reputation: 195
For location
is , let's say, "/data/mybackup/data/fil1"
and exclude
is "/data/archive"
, the location
variable doesn't start with "/data/archive"
.
As you have a "/data"
value in your excludes
list, you don't need to put another path that starts with "/data"
. So if you define excludes = ["/data", "/ebooks"]
there will be no problem.
Upvotes: 2
Reputation: 646
You have to check all excludes before printing the location.
Try changing this:
for location in locations:
for exclude in excludes:
if not location.startswith(exclude):
print(location)
break
To:
def valid(location):
for exclude in excludes:
if location.startswith(exclude):
return False
return True
for location in locations:
if valid(location):
print(location)
Upvotes: 1