Shared publicly  - 
 
I just learned in Python you can do a_string.startswith(('option1', 'option2')) – i.e. give startswith and endswith a tuple.
47
13
Christian Heimes's profile photoWilliam Cannon's profile photoDuncan McGreggor's profile photoDavid Mertz's profile photo
21 comments
 
Nice. I just learned something that might be useful.
 
Interesting. I hadn't realized that was part of the startswith signature. Good to know! Any idea as to when it was added or has it always supported it?
 
Works in 2.5, probably forever?
 
That's neat. On the glass is half-empty side, it doesn't take a set. ;)
 
Checked Python Docs: Changed in version 2.5: Accept tuples as prefix.

Who knew :x
 
isinstance() is another example of a useful function that takes a tuple as argument. It's very useful in combination with ABCs, e.g. isinstance(var, numbers.Number) works for long, int, float and 3rd party numbers.
 
"Changed in version 2.5: Accept tuples as prefix." - guess I never looked that up in the docs since 2.4 ;)
 
Indeed, I was happily surprised to learn about this useful feature via python-ideas for once rather than the usual crazy discussions.
 
I'm ashamed to say I did not know this either! This would have saved me a whole lot of awkward code over my life if I had realized it for the last 8 years or whatever.
 
Actually, I think the situation is even worse. I think I once knew this and forgot it along the way... it dimly rings a bell. But I am sure I have written this sort of code more than once in the meanwhile:

Match = False
for prefix in ('this','that', 'other') :
if a_string.startswith(prefix):
Match = True
if Match: ...
 
+David Mertz Until today I usually did something along:

if any(a_string.startswith(x) for x in ("this", "that", "other")):
# do something

any() and all() can really save you some lines of code :)
 
If if was accepting iterables startswith("ABC") would be ambiguous.
 
+Łukasz Rekucki I definitely dig on any() and all(); I should probably use those even more often. Strictly speaking my example (with broken indentation) is indeed expressible as you rewrite it with any() -- and of course even more easily as Ian suggests with passing a tuple -- but I find myself using that somewhat ugly pattern of using a flag variable much too often. If some more stuff happens in the loop, you can't as easily reduce it to one any(), nor to some better initial boolean expression. But I still always feel like I haven't thought about the problem in the best way whenever I use such a throwaway variable to decide if some condition has been met... but it still sometimes seems like the quickest way to get something done.
 
+David Mertz I think you can reduce it to any() (and maybe some helper function) as long as you don't need to know which value(s) satisfy your condition. filter() lets you get all the matching values. What I'm always missing in Python is something that would return the first matching value.
 
+Łukasz Rekucki Well, of course you can always use:

first_match = filter(pred, seq)[0]

But if 'seq' is long, you've wasted complete application of 'pred'. You could use ifilter and islice, but that starts to look unwieldy. It's probably easiest just to write your own first(), don't you think?

def first(iter, pred):
for x in iter:
if pred(x): return x
return None

It might be nice to make that a built-in, but it's pretty simple to implement.
 
+David Mertz You just need to remember to use any() instead, if you search for None :)
 
Nice. How did I not know that?
Add a comment...