Python Forum
Python: if 'X' in 'Y' but with two similar strings as 'X'
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python: if 'X' in 'Y' but with two similar strings as 'X'
#1
The title makes this really confusing. Hopefully it isn't.

In the title I used 'X' and 'Y'. 'X' is a string url: https://i.imgur.com/7Ic4AMO.gifv and 'Y' is what I want to check for in the string.

Take this code:
if '.gif' in X:
    print("HELLO")
elif '.gifv' in X:
    print("PLEASE PRINT THIS")
No matter if it has '.gif' or '.gifv' in the url, it will always print 'HELLO'. That occurs because '.gifv' also includes '.gif' so it never makes it to the next part of the if statement.
I have also tried:
X.endswith('.gifv') / X.endswith('.gif')
but it always returns false.

How can I work around this? Would changing the order of the if statement work?

Thanks,
Dream
Reply
#2
If you change order of checks you will get desired results:

if '.gifv' in X:              # true only if '.gifv' is present, skips '.gif'
    # do something
elif '.gif' in X:
    # do something else
You had this, but why didn't you try it yourself?
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#3
(Jan-31-2019, 09:38 AM)perfringo Wrote: If you change order of checks you will get desired results:

if '.gifv' in X:              # true only if '.gifv' is present, skips '.gif'
    # do something
elif '.gif' in X:
    # do something else
You had this, but why didn't you try it yourself?

Thanks for the reply,

I got the idea at the time of posting but waited to see if there were other ways.

Dream
Reply
#4
(Jan-31-2019, 09:42 AM)DreamingInsanity Wrote: I got the idea at the time of posting but waited to see if there were other ways.

There are many other ways how to do it (including your endswith).

However, suggesting the 'other ways' one must know what is the end goal (what do you want accomplish). For printing out this solution is good enough. But your objective is probably not to just print out something. If there is match you probably want to act upon this information. Therefore to present 'other ways' one must know what you want to do after match is found.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#5
if you want to check string end, better use some_string.endswith(search_string). in checks for membership, so it will return True even if the search_string is in the middle of some_string. .endswith() is also recommened by PEP8 compared to using slicing.
Alternative approach is using something like

def spam():
    print('Doing something within spam()')
    
def eggs():
    print('Doing something within eggs()')
    
options = (('gifv', spam), ('gif', eggs))

some_string = 'foo.gifv'
for end, func in options:
    if some_string.endswith(end):
        func()
        break
This way it will allow to expand the list of options without ending with monstrous if/elif/elif/.../else block.
Options can be dict in python 3.7 or collections.OrderedDict (in version before that) in order to preserve the order in which will be checked
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#6
(Jan-31-2019, 10:13 AM)perfringo Wrote:
(Jan-31-2019, 09:42 AM)DreamingInsanity Wrote: I got the idea at the time of posting but waited to see if there were other ways.

There are many other ways how to do it (including your endswith).

However, suggesting the 'other ways' one must know what is the end goal (what do you want accomplish). For printing out this solution is good enough. But your objective is probably not to just print out something. If there is match you probably want to act upon this information. Therefore to present 'other ways' one must know what you want to do after match is found.

The only part that wasnt included in the code was that once it found what ending the url had, it would call a function and it would download the file from that url. I needed the ending so I could save it with that specific ending.
urllib.request.urlretrieve(url, img_dir + str(name) + '.gif') / urllib.request.urlretrieve(url, img_dir + str(name) + '.gifv')  
Thanks,
Dream

(Jan-31-2019, 10:59 AM)buran Wrote: if you want to check string end, better use some_string.endswith(search_string). in checks for membership, so it will return True even if the search_string is in the middle of some_string. .endswith() is also recommened by PEP8 compared to using slicing.
Alternative approach is using something like

def spam():
    print('Doing something within spam()')
    
def eggs():
    print('Doing something within eggs()')
    
options = (('gifv', spam), ('gif', eggs))

some_string = 'foo.gifv'
for end, func in options:
    if some_string.endswith(end):
        func()
        break
This way it will allow to expand the list of options without ending with monstrous if/elif/elif/.../else block.
Options can be dict in python 3.7 or collections.OrderedDict (in version before that) in order to preserve the order in which will be checked

Thanks, I will use this in the future!

Dream
Reply
#7
(Feb-01-2019, 09:47 AM)DreamingInsanity Wrote: he only part that wasnt included in the code was that once it found what ending the url had, it would call a function and it would download the file from that url. I needed the ending so I could save it with that specific ending.

That's great example that one should be clear what ultimate goal is.
Instead of checking extensions one by one, you should use proper tools to extract file extension from url

import os
import pathlib

url1 = 'https://www.somedomain.com?download=somefile.div'
url2 = 'https://www.somedomain.com/somefile.divf'

#using os.path.splitext
for url in (url1, url2):
    ext = os.path.splitext(url)[-1]
    local_path = f'c:/somefolder/localfile{ext}'
    print(f'{url} --> {local_path}')
    
print()
# using pathlib
for url in (url1, url2):
    ext = pathlib.Path(url).suffix
    local_path = f'c:/somefolder/localfile{ext}'
    print(f'{url} --> {local_path}')
Output:
https://www.somedomain.com?download=somefile.div --> c:/somefolder/localfile.div https://www.somedomain.com/somefile.divf --> c:/somefolder/localfile.divf https://www.somedomain.com?download=somefile.div --> c:/somefolder/localfile.div https://www.somedomain.com/somefile.divf --> c:/somefolder/localfile.divf >>>
EDIT: I just realised that you may have a case when it url does not end in desired extension.
In this case you may want to check that extension is in predefined list of "eligible" extemsions.
Also instead of using os and pathlib module you can split url string at '.', take the last element and check if it is in the desired list of extensions.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Trying to understand strings and lists of strings Konstantin23 2 699 Aug-06-2023, 11:42 AM
Last Post: deanhystad
  Splitting strings in list of strings jesse68 3 1,703 Mar-02-2022, 05:15 PM
Last Post: DeaD_EyE
  Sum similar items tester_V 3 1,903 Jun-29-2021, 06:58 AM
Last Post: tester_V
  Finding multiple strings between the two same strings Slither 1 2,482 Jun-05-2019, 09:02 PM
Last Post: Yoriz
  Splitting strings in python? NLittle17 3 2,344 Jan-05-2019, 09:20 AM
Last Post: Axel_Erfurt
  Similar to Poker bluekade5050 1 27,935 Nov-14-2018, 04:46 PM
Last Post: j.crater
  lists, strings, and byte strings Skaperen 2 4,181 Mar-02-2018, 02:12 AM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020