Watch the video first to see string membership in action, then read on for the detail and worked examples you can use straight away.
What String Membership Is
String membership is the ability to check whether a character, word, or sequence of characters exists inside a larger string. It answers a simple question: is this text in that text? In Python, this is called substring search, and you do it with the in and not in operators. Both return True or False.
This matters in banking workflows constantly: validating transaction descriptions, checking whether a payment instruction contains a specific keyword, filtering counterparty names, or ensuring regulatory text appears in a report.
The in and not in Operators
How in Works
The in operator checks whether a substring exists anywhere inside a string. If it does, it returns True. If not, it returns False.
text = "Payment received from ABC Corporation"
print("ABC" in text) # True
print("XYZ" in text) # False
The substring can be a single character, a word, or any sequence of characters. Python searches the entire string for an exact match of that sequence.
transaction = "SWIFT payment to Deutsche Bank"
print("SWIFT" in transaction) # True
print("payment" in transaction) # True
print("Deutsche" in transaction) # True
print("sterling" in transaction) # False
How not in Works
The not in operator does the opposite. It returns True if the substring is not found, and False if it is found.
text = "Payment received from ABC Corporation"
print("XYZ" not in text) # True (XYZ is not in the text)
print("ABC" not in text) # False (ABC is in the text)
This is useful when you want to check that something is absent, or to validate exclusions.
Case sensitivity matters
String membership in Python is case sensitive. "PAYMENT" is not the same as "payment". This catches many implementations. In finance workflows where data arrives mixed case, exact matching can cause validation failures.
description = "Payment to supplier"
print("PAYMENT" in description) # False (uppercase P)
print("payment" in description) # True (lowercase p)
print("Payment" in description) # True (exact case match)
This is actually useful. It lets you be precise. But if you need to match regardless of case, you must convert the string first (more on that below).
Real Finance Examples
Checking Transaction Types
In a cash flow or payments system, you often receive transaction descriptions in a standard format but need to classify them or validate them against expected patterns.
def is_wire_payment(description):
return "SWIFT" in description or "wire" in description
def is_standing_order(description):
return "standing order" in description.lower()
tx1 = "SWIFT payment to counterparty ABC"
tx2 = "Standing Order monthly rent"
tx3 = "Internal transfer"
print(is_wire_payment(tx1)) # True
print(is_standing_order(tx2)) # True
print(is_standing_order(tx3)) # False
Notice the use of .lower() in the standing order check. This converts the description to lowercase before checking, so it works regardless of how the input was capitalised.
Validating Regulatory Keywords
A weekly note on treasury, liquidity and practical Python. No spam, unsubscribe any time.
When building compliance or regulatory reporting tools, you often need to flag transactions or accounts that contain certain keywords.
def has_sanctioned_terms(counterparty_name):
banned_words = ["Iran", "Syria", "North Korea", "Cuba"]
for word in banned_words:
if word in counterparty_name:
return True
return False
counterparty = "Trade Corp Iran Limited"
if has_sanctioned_terms(counterparty):
print("Flag for compliance review") # This will print
This is illustrative only. Real compliance screening uses authoritative lists maintained by regulators and designated authorities.
You can write this more concisely using any():
def has_sanctioned_terms(counterparty_name):
banned_words = ["Iran", "Syria", "North Korea", "Cuba"]
return any(word in counterparty_name for word in banned_words)
print(has_sanctioned_terms("Trade Corp Iran Limited")) # True
print(has_sanctioned_terms("Smith & Co")) # False
Building a Payment Instruction Parser
Suppose you receive payment instructions as unstructured text and need to extract and validate key information. Membership checks help you detect required fields.
def validate_payment_instruction(instruction):
required = ["amount", "beneficiary", "date"]
missing = []
for field in required:
if field.lower() not in instruction.lower():
missing.append(field)
if missing:
return False, f"Missing fields: {', '.join(missing)}"
else:
return True, "Instruction complete"
instr1 = "Pay amount 50000 to beneficiary Jones Inc on date 2024-01-15"
instr2 = "Pay 50000 to Jones Inc"
valid1, msg1 = validate_payment_instruction(instr1)
valid2, msg2 = validate_payment_instruction(instr2)
print(valid1, msg1) # True, Instruction complete
print(valid2, msg2) # False, Missing fields: date
Combining Membership with Other Tools
Cleaning Input Before Checking
Real data is messy. User input arrives with extra spaces, mixed case, and inconsistent formatting. Clean it before you check.
def check_payment_status(status_input):
status = status_input.strip().lower()
if "complete" in status:
return "Payment completed"
elif "pending" in status:
return "Payment pending"
elif "failed" in status:
return "Payment failed"
else:
return "Status unknown"
print(check_payment_status(" COMPLETE ")) # Payment completed
print(check_payment_status("Pending...")) # Payment pending
The .strip() method removes leading and trailing whitespace. The .lower() method converts to lowercase. Both are essential before membership checks on user input.
Membership in Conditional Logic
Combine membership checks with if statements to build robust decision logic.
def process_transaction(description, amount):
if "reversal" in description.lower():
print(f"Flagged: Reversal detected. Amount: {amount}")
if amount > 100000 and "wire" not in description.lower():
print(f"Alert: Large amount without wire confirmation")
if any(keyword in description.lower() for keyword in ["test", "demo", "sample"]):
print("Filtered: Test transaction not processed")
else:
print(f"Processing: {description} for {amount}")
process_transaction("SWIFT wire payment test", 50000)
process_transaction("Payment to supplier", 150000)
Common Gotchas and Best Practice
Case sensitivity. Always think about case. If you are checking user input or external data, use .lower() or .upper() to normalise it first. If exact case matters (like matching a regulated term), leave it as is.
Substring matching is literal. "pay" in "payment" returns True. If you only want exact word matches, you need more sophisticated tools (regex, or splitting into words). For most finance work, literal substring matching is fine.
Performance. The in operator is fast, even for long strings. Python searches efficiently. You do not need to worry about performance for typical transaction descriptions or counterparty names.
Whitespace. Remember that spaces and line breaks are part of the string. "John" in "John Smith" returns True, but "John Smith" in "JohnSmith" returns False.
Always strip and normalise user input before membership checks. Use .strip() to remove extra spaces, and .lower() to handle case variations. This prevents validation bypasses and ensures consistent behaviour across different data sources.
What Comes Next
String membership is one of three key ways to work with text in Python. Earlier sessions covered indexing and slicing (accessing parts of a string by position). Membership checks let you search for content. Next, you will explore string methods like .replace(), .split(), and .find() which give you even finer control over text processing.
In the context of your finance work, string membership is the foundation for validation, filtering, and conditional logic. Pair it with the tools you learned in earlier sessions, particularly how to work with numbers and conditions, and you have the core toolkit for building real applications.
Try this with your own transaction feeds, counterparty lists, or payment instructions. Pull a real dataset and write membership checks to validate or classify it. The more you work with actual text, the faster these patterns will become second nature.

The Complete Python Course
Welcome to the most practical and beginner friendly Python Bootcamp Course on YouTube.
Take the courseGet the next one in your inbox
A weekly note across Finance & Treasury, Innovation & Automation and Career Development. No spam, unsubscribe any time.
Notes across finance and treasury, innovation and automation, and career development, written by practitioners who do the work.
