I'm developing a Python program to detect names of cities in a list of records. The code I've developed so far is the following:
aCities = ['MELBOURNE', 'SYDNEY', 'PERTH', 'DUBAI', 'LONDON']
cxTrx = db.cursor()
cxTrx.execute( 'SELECT desc FROM AccountingRecords' )
for row in cxTrx.fetchall() :
if any( city in row[0] for city in aCities ) :
#print the name of the city that fired the any() function
else :
# no city name found in the accounting record
The code works well to detect when a city in the aCities' list is found in the accounting record but as the any() function just returns True or False I'm struggling to know which city (Melbourne, Sydney, Perth, Dubai or London) triggered the exit.
I've tried with aCities.index and queue but no success so far.
I don't think it's possible with any
. You can use next
with default value:
for row in cxTrx.fetchall() :
city = next((city for city in aCities if city in row[0]), None)
if city is not None:
#print the name of the city that fired the any() function
else :
# no city name found in the accounting record
You won't because any
returns only a boolean value. But you can use next
:
city = next((city for city in aCities if city in row[0]), None)
if city:
...
With this syntax you'll find the first city
that is a substring of the description stored in the database row. If there isn't one, the second parameter e.g. None, will be returned.
No, it is possible with any
. It's a bit of a stunt - it "reads funny" - but it does work:
if any(city in row[0] and not print(city) for city in aCities):
# city in row[0] found, and already printed :)
# do whatever else you might want to do
else:
# no city name found in the accounting record
or more concisely, if all you really want to do is print the city:
if not any(city in row[0] and not print(city) for city in aCities):
# no city name found in the accounting record
It works for three reasons:
any
stops at the first true (truthy) item,and
is short-circuiting, so not print(city)
will only be eval'd if city in row[0]
is true, andprint
returns None
, so not print(...)
is always True
.PS: As @falsetru points out, in Python 2.x print
isn't a function, so you'll have to first say:
from __future__ import print_function
As I said, it works for 3 reasons - Python 3 reasons ;) Oh, wait - that's 4 reasons...
For completeness, here is a solution with a standard for-loop:
for city in aCities:
if city in row[0]:
print 'Found city', city
break
else:
print 'Did not find any city'
This should have the same short-circuit behavior as any
, since it breaks out of the for-loop when the condition is fulfilled. The else
part is executed when the for-loop runs till the end without breaking, see this question.
Although this solution uses more lines, it actually uses less characters than the other solutions, since there is no call to next(..., None)
, it does not have the extra city =
assignment and there is no second if city is None
(at the cost of one extra break
). When things get more complicated, it is sometimes clearer to write out the for-loop explicitly, then to string together some generator expressions and next
statements.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With