CSmith
CSmith

Reputation: 33

Pythonic way to find if a string contains multiple values?

I am trying to find through a list of files all the excel, txt or csv files and append them to a list

goodAttachments = [i for i in attachments if str(i).split('.')[1].find(['xlsx','csv','txt'])

This is obviously not working because find() needs a string and not a list. Should I try a list comprehension inside of a list comprehension?

Upvotes: 1

Views: 126

Answers (5)

Farhan.K
Farhan.K

Reputation: 3485

There's no need to split or use double list comprehension. You can use str.endswith which takes a tuple of strings to check as an argument:

goodAttachments = [i for i in attachments if str(i).endswith(('.xlsx', '.csv', '.txt'))]

If you really want to split:

goodAttachments = [i for i in attachments if str(i).split('.')[-1] in ('xlsx', 'csv', 'txt')]

The first way is better as it accounts for files with no extension.

Upvotes: 4

jsones
jsones

Reputation: 91

You could try something like this:

goodAttachments = [i for i in attachments if str(i).split('.')[-1] in ['xlsx', 'csv', 'txt']]

This will check if the extension after the last '.' matches one of 'xlsx', 'csv', or 'txt' exactly.

Upvotes: 1

freebie
freebie

Reputation: 1947

I would suggest maybe adding a few more lines then trying to create a one-liner with nested list comprehensions. Though that would work, I think it makes more readable code to split these comprehensions out onto separate lines.

import os

attachments = ['sadf.asdf', 'asd/asd/asd.xslx']
whitelist = {'.xslx', '.csv'}

extentions = (os.path.split(fp)[1] for fp in attachments)
good_attachments = [fp for fp, ext in zip(attachments, extentions) if ext in whitelist]

I've also used os.path.split over str.split as the file may have multiple dots present and this split is designed for this exact job.

Upvotes: 0

Alex Stiff
Alex Stiff

Reputation: 904

You can check that everything after the last dot is present in a second list. using [-1] instead of [1] ensures that files named like.this.txt will return the last split txt and not this.

goodAttachments = [i for i in attachments if str(i).split('.')[-1] in ['xlsx','csv','txt']]

Upvotes: 0

Rocky Li
Rocky Li

Reputation: 5958

[i for i in attachments if any([e in str(i).split('.')[1] for e in ['xlsx','csv','txt']]))

Like you said, nested list comprehension.

Edit: This will work without splitting, I was trying to replicate the logic in find.

Upvotes: 0

Related Questions