Python tips and tricks for competitive programming

Here are some Python hacks for competitive programming that can help you write efficient and concise code.

String Operation

Join

  • The join() method takes all items in an iterable and joins them into one string.
  • A string must be specified as the separator.
  • Iterable –> string

Synatx

string.join(iterable)
Python

Example

myTuple = ("John", "Peter", "Vicky")
x = "->".join(myTuple)
print(x) #John->Peter->Vicky


myList = ["John", "Peter", "Vicky"]
x = "".join(myList)
print(x) #JohnPeterVicky
Python

Perform join in integer


lst = ['1','2','3','4']
print("".join(lst)) #1234

lst = [1,2,3,4]
print("".join(lst)) #TypeError: sequence item 0: expected str instance, int found
Python

Solution

lst = [1,2,3,4]
print("".join(map(str,lst))) #1234
Python

Dictionary

When using a dictionary as an iterable, the returned values are the keys, not the values.

myDict = {"name": "John", "country": "Norway"}
mySeparator = "="

x = mySeparator.join(myDict)

print(x) #name=country
Python

Split

The split() method splits a string into a list.

You can specify the separator, default separator is any whitespace.

Syntax

string.split(separator, maxsplit)
Python

  • separator Optional. Specifies the separator to use when splitting the string. By default any whitespace is a separator
  • maxsplit Optional. Specifies how many splits to do. Default value is -1, which is “all occurrences”

Example

txt = "welcome to the jungle"

x = txt.split()

print(x) # ['welcome', 'to', 'the', 'jungle']

txt = "hello, my name is Peter, I am 26 years old"

x = txt.split()
y = txt.split(", ")
z = txt.split(", ",1)

print(x) # ['hello,', 'my', 'name', 'is', 'Peter,', 'I', 'am', '26', 'years', 'old']
print(y) # ['hello', 'my name is Peter', 'I am 26 years old']
print(z) # ['hello', 'my name is Peter, I am 26 years old']
Python

strip()

  • The strip() method removes any leading, and trailing whitespaces.
  • Leading means at the beginning of the string, trailing means at the end.
  • You can specify which character(s) to remove, if not, any whitespaces will be removed.

Syntax

string.strip(characters)
Python

Example

txt = "     banana     "
x = txt.strip()
print(x)   # banana


txt = ",,,,,rrttgg.....banana....rrr"
x = txt.strip(",.grt") #  banana
print(x)
Python

“,.grt” –> stripping , . g r t

rstrip and lstrip

  • The lstrip() method removes any leading characters (space is the default leading character to remove)
  • The rstrip() method removes any trailing characters (characters at the end a string), space is the default trailing character to remove.

txt = "...banana,,,,,ssqqqww....."

print(txt.rstrip(",.qsw")) # ...banana
print(txt.lstrip(",.qsw")) # banana,,,,,ssqqqww.....
Python

index() and find()

find()

  • The find() method finds the first occurrence of the specified value.
  • The find() method returns -1 if the value is not found.

index()

  • The index() method finds the first occurrence of the specified value.
  • The index() method raises an exception if the value is not found.

Syntax

string.index(value, start, end)
string.find(value, start, end)
Python

Example

txt = "Mi casa, su casa."

print(txt.find("casa")) # 3
print(txt.index("casa")) # 3

print(txt.find("hi")) # -1
#print(txt.index("hi")) # error ValueError: substring not found
Python

rindex() and rfind()

rfind()

  • The rfind() method finds the last occurrence of the specified value.
  • The rfind() method returns -1 if the value is not found.

rindex()

  • The rindex() method finds the last occurrence of the specified value.
  • The rindex() method raises an exception if the value is not found.

Syntax

string.rfind(value, start, end)

string.rindex(value, start, end)
Python

Example

txt = "Mi casa, su casa."

print(txt.rfind("casa")) # 12
print(txt.rindex("casa")) # 12

print(txt.rfind("hi")) # -1
print(txt.rindex("hi")) # error ValueError: substring not found
Python

Find out all occurrence

result = []

lst = "my name is backendmesh"

index = lst.find("m")
while(index>-1):
    result.append(index)
    lst = lst[index+1:]
    index = lst.find("m")

print(result) #[0, 4, 12]
Python

partition()

  • The partition() method searches for a specified string, and splits the string into a tuple containing three elements.
  • The first element contains the part before the specified string.
  • The second element contains the specified string.
  • The third element contains the part after the string.
txt = "I could eat bananas all day"

x = txt.partition("bananas") 

print(x) # ('I could eat ', 'bananas', ' all day')
Python

replace()

The replace() method replaces a specified phrase with another specified phrase.

string.replace(oldvalue, newvalue, count)
Python

  • oldvalue Required. The string to search for
  • newvalue Required. The string to replace the old value with
  • count Optional. A number specifying how many occurrences of the old value you want to replace. Default is all occurrences
txt = "one one one one"

print(txt.replace("one", "three")) # three three three three
print(txt.replace("one", "three", 2)) # three three one one
Python

String to list


#String to list
word = "hello"
print(list(word)) #['h', 'e', 'l', 'l', 'o']


#list to string
lst = ['h', 'e', 'l', 'l', 'o']
print("".join(lst)) #hello
Python

String to ASCII

print(ord('a')) #97
print(ord('A')) #65
Python

Question: Assign A=1,……Z=26

print(ord('A')-64) #1
print(ord('Z')-64) #26

OR 

print(ord('A')-ord('A')+1) #1
print(ord('Z')-ord('A')+1) #26
Python

ASCII to String


print(chr(97)) #a
print(chr(65)) #A
Python

Loops

Range

  • range(start, stop, step)
  • Generates numbers from start to stop – 1, incrementing by step.
for i in range(2,n) # 2 to n-1
for i in range(0,n) # 0 to n-1
for i in range(0,n,2) # 0,2,4,6 ...
for i in range(n) # 0 to n-1
for i in range(n,0,-1) # n to 1
for i in range(n,-1,-1) # n to 0
Python

Array/List

Python does not have built-in support for arrays like other languages (C, Java), but lists can be used as dynamic arrays.

Initialisation with Default value

arr = [0] * 10  # Creates an array of size 10 with all elements as 0
arr = [1] * 10  # Creates an array of size 10 with all elements as 1
Python

Delete

Delete an element from a list.

Way 1: Using remove() (by value):

my_list = [1, 2, 3, 4, 5,3]
my_list.remove(3)  # Removes the first occurrence of 3
print(my_list)  # [1, 2, 4, 5, 3]
Python

Way 2: Slice

my_list = [1, 2, 3, 4, 5,3]
my_list = my_list[:2]+my_list[3:] # 0 to 1 and 3 to end
print(my_list)
Python

Way 3: Using pop() (by index):

my_list = [1, 2, 3, 4, 5, 3]
my_list.pop(2)  # Removes the element at index 2 (which is 3)
print(my_list)  # [1, 2, 4, 5, 3]
Python

Way 4: Using del (by index):

my_list = [1, 2, 3, 4, 5, 3]
del my_list[2]  # Deletes the element at index 2
print(my_list)  # [1, 2, 4, 5, 3]
Python

pop vs del

Featurepop()del
PurposeRemoves an element and returns itJust deletes the element (no return)
Usagelist.pop(index)del list[index]
DefaultIf no index, removes last item (pop())No default; you must give an index or slice
Error on wrong indexYes (IndexError)Yes (IndexError)
Return valueYes, returns the removed itemNo, just deletes

with power comes responsibility

length = len(nums)
for i in range(0, length):   
    nums.pop(i). #IndexError: pop index out of range
Python

  • gives an error because you are modifying the list (pop) while looping through it forward — but when you pop(i), the list shrinks, and the indices shift!

👉 So i becomes out of range very quickly.

Example:

nums = [10, 20, 30, 40, 50]

for i in range(2, length):   
    nums.pop(i). #IndexError: pop index out of range
    #or 
    #del nums[i]

explanation
del nums[2] # [10, 20, 40, 50]
del nums[3] # [10,20,40]
del nums[4] # error
Python

  • i = 2, you pop(2), list becomes [10, 20, 40, 50]
  • Now i = 3, but after pop, the list is smaller, so nums[3] = 50 is still OK
  • Then i = 4, but now list length is only 4, so nums[4] ❌ IndexError.

Solution 1 :slice

del nums[j:]
Python

Solution 2 : Loop backward (so popping doesn’t affect upcoming elements):

length = len(nums)
for i in range(length-1, j-1, -1):   
    nums.pop(i)
Python

Negative index in List

lst = [1,2,3,4,5,6,7,8,9]
print(lst[-1]) #9
print(lst[-2]) #8
print(lst[-3]) #7
Python

Dictionary

Default Value

Instead of manually checking if a key exists in a dictionary, use defaultdict.

from collections import defaultdict

my_dict = {}
my_dict['a'] = 4
print(my_dict['a']) # 4
print(my_dict['b']) # error KeyError: 'b'

d = defaultdict(int)  # Default value is 0
d['a'] = 1
print(d['a'])  # 1
print(d['b'])  # 0 (instead of KeyError)

my_dict = defaultdict(int)
print(my_dict['my_key']) # 0
my_dict = defaultdict(list)
print(my_dict['my_key']) # []
Python

Default Values

  • int : 0
  • float : 0.0
  • str : ”
  • bool : False

Why?

Without defaultdict: Everytime before using value , we needs to check if exist

counts = {}
words = ['apple', 'banana', 'apple']

for word in words:
    if word in counts:
        counts[word] += 1
    else:
        counts[word] = 1
Python

With defaultdict:

from collections import defaultdict

counts = defaultdict(int)  # int() defaults to 0

for word in ['apple', 'banana', 'apple']:
    counts[word] += 1

print(counts)
Python

  • It’s shorthand
  • count[‘any_key’] will never throw an error. Will always get a default value

Example 2

List as default value

from collections import defaultdict

d = defaultdict(list)   # Automatically assigns an empty list as the default value
d['a'].append(10)       # Since 'a' doesn't exist, it's initialized to [] first, then 10 is appended
print(d['a'])           # Output: [10]

print(d['b'])    # []
Python

Swap Two Variables

a, b = 5, 10
a, b = b, a
print(a, b)  # 10, 5
Python

Additional variable not required

It’s very usefully and handy to use.

Example: Reverse a list

arr = [1, 2, 3, 4, 5,6,7,8,9,10]
start = 0
lst   = len(arr)-1

while start<=lst:
    arr[lst],arr[start] = arr[start],arr[lst]
    start+=1
    lst-=1

print(arr)
Python

Use itertools for Combinations & Permutations

from itertools import permutations, combinations
print(list(permutations([1, 2, 3], 2)))  # [(1,2), (1,3), (2,1), ...]
print(list(combinations([1, 2, 3], 2)))  # [(1,2), (1,3), (2,3)]
Python

Use enumerate to Avoid Extra Index Handling

arr = [10, 20, 30]
for i, val in enumerate(arr, start=1):
    print(i, val)
Python

Use divmod() for Simultaneous Quotient & Remainder

q, r = divmod(10, 3)
print(q, r)  # 3 1
Python

Use enumerate() for Cleaner Loops

Instead of:

arr = [10, 20, 30]
for i in range(len(arr)):
    print(i, arr[i])
Python

Use:

for i, val in enumerate(arr, start=1):
    print(i, val)
Python

Reverse a String or List in One Line

s = "hello"
print(s[::-1])  # "olleh"

arr = [1, 2, 3, 4]
print(arr[::-1])  # [4, 3, 2, 1]
Python

For in-place list reversal (better performance):

arr.reverse()
Python

This will not work for string

reversed()

  • It works on sequences like lists, tuples, strings, etc.
  • It does not modify the original sequence; it just gives you the items in reverse order.
  • Since it returns an iterator, if you want a reversed list, you can do:
reversed_list = list(reversed(my_list))
print(reversed_list)
# Output: [5, 4, 3, 2, 1]



word = "hello"
print(reversed(word)) #<reversed object at 0x100c27d60>
print(''.join(reversed(word)))  # Output: "olleh"
Python

Take out every thing except ‘i’ element

lst = [1,2,3,4,5,6,7,8]
i =3
current   = lst[i]
remaining = lst[:i]+lst[i+1:]


print(current)   # 4
print(remaining) # [1, 2, 3, 5, 6, 7, 8]
Python

One-Liner If-Else (Ternary Operator)

Instead of:

x = 10
if x > 5:
    y = "big"
else:
    y = "small"
Python

Use:

y = "big" if x > 5 else "small"
Python

Find Unique Elements in a List Faster

arr = [1, 2, 2, 3, 3, 4]

unique_arr = list(set(arr))
print(unique_arr)
Python

a = path vs a = path[:]

In Python, assigning a list can either create a reference or a copy:

  • a = path creates a reference to the same list. Changes to a will affect path and vice versa.
  • a = path[:] creates a shallow copy of the list. Changes to a will not affect path.

Use a = path[:] when:

  • You want to preserve the original list.
  • You’re in recursive or backtracking algorithms and need a snapshot of the current state.

Use a = path when:

  • You want to modify the original list through another name.
  • You don’t need to preserve the original list.

In backtracking, always use res.append(path[:]) to avoid bugs from shared list references.Refer

Common List Lengths in String/Array Operations

OperationList LengthReason
String Multiplication[0] * (len(num1) + len(num2))Max digits in result = m + n
String Addition[0] * (max(len(num1), len(num2)) + 1)One extra digit possible from carry
Array Number Addition[0] * (max(len(arr1), len(arr2)) + 1)Same as string addition
Polynomial Multiplication[0] * (len(A) + len(B) - 1)Degree of result = (m-1) + (n-1)
Prefix Sum Array[0] * (len(nums) + 1)Extra space for simpler range sum queries
Suffix Sum Array[0] * (len(nums) + 1)Similar to prefix sum, but in reverse
1D DP Array[0] * (n + 1)Space for base cases and up to n
2D DP Table[[0] * (m + 1) for _ in range(n + 1)]For problems needing rows × cols + base cases

Multi-key sorting

Sorting by multiple columns

Example

employees = [
    {"name": "Zara", "age": 25, "salary": 90000},
    {"name": "Alex", "age": 30, "salary": 90000},
    {"name": "Mike", "age": 25, "salary": 80000},
    {"name": "Bob", "age": 30, "salary": 80000},
]
Python

Sorting Priorities:

  • Salary → descending (highest salary first)
  • Age → ascending (youngest first)
  • Name → lexicographically (alphabetical order)

Expected Output

[
    {"name": "Zara", "age": 25, "salary": 90000},  # Salary 90k, youngest in 90k group
    {"name": "Alex", "age": 30, "salary": 90000},  # Same salary, older
    {"name": "Mike", "age": 25, "salary": 80000},  # Salary 80k, youngest in 80k group
    {"name": "Bob", "age": 30, "salary": 80000},   # Same salary, older
]

Python

Follow same priority order as it is.

employees = [
    {"name": "Zara", "age": 25, "salary": 90000},
    {"name": "Alex", "age": 30, "salary": 90000},
    {"name": "Mike", "age": 25, "salary": 80000},
    {"name": "Bob", "age": 30, "salary": 80000},
]



Step 1  Salary → descending (highest salary first)

employees = [
    {"name": "Zara", "age": 25, "salary": 90000},
    {"name": "Alex", "age": 30, "salary": 90000},
    {"name": "Mike", "age": 25, "salary": 80000},
    {"name": "Bob", "age": 30, "salary": 80000},
]




Step 2 Age → ascending (youngest first)

employees = [
    {"name": "Zara", "age": 25, "salary": 90000},
     {"name": "Mike", "age": 25, "salary": 80000},
    {"name": "Alex", "age": 30, "salary": 90000},
    {"name": "Bob", "age": 30, "salary": 80000},
]

Step 3  : Name → lexicographically (alphabetical order)

Our Output

employees = [
      {"name": "Alex", "age": 30, "salary": 90000},
    {"name": "Bob", "age": 30, "salary": 80000},
     {"name": "Mike", "age": 25, "salary": 80000},
    {"name": "Zara", "age": 25, "salary": 90000},
    
]




Expected Output

[
    {"name": "Zara", "age": 25, "salary": 90000},  # Salary 90k, youngest in 90k group
    {"name": "Alex", "age": 30, "salary": 90000},  # Same salary, older
    {"name": "Mike", "age": 25, "salary": 80000},  # Salary 80k, youngest in 80k group
    {"name": "Bob", "age": 30, "salary": 80000},   # Same salary, older
]
Python

Why this is wrong:

  • Sorting by age after sorting by salary does not preserve the salary order because you’re sorting the full list again, not just within salary groups.
  • Sorting by name last again sorts the whole list, destroying the previous order completely.

Reverse priority orde

When sorting by multiple columns, apply the last rule first and first rule last, to preserve priority.”

Note:

  • If you want to sort by multiple criteria (say, A then B), the primary sort key should be applied last.
  • The secondary (and less important) sort keys should be applied first.

This is because each successive sort must preserve the order of the previous more important sort — and this is only guaranteed when the sorting is stable (i.e., elements with equal keys retain their relative order).

Why this works:

Sorting from least to most important key (i.e., last rule first) ensures that when a more important rule is applied later, it groups the items while keeping the relative order imposed by less important rules.

This avoids overwriting the priority of the more important keys.

Example

employees = [
    {"name": "Zara", "age": 25, "salary": 90000},
    {"name": "Alex", "age": 30, "salary": 90000},
    {"name": "Mike", "age": 25, "salary": 80000},
    {"name": "Bob", "age": 30, "salary": 80000},
]


Step 1 :Name → lexicographically (alphabetical order) 

employees = [
    {"name": "Alex", "age": 30, "salary": 90000},
    {"name": "Bob", "age": 30, "salary": 80000},
    {"name": "Mike", "age": 25, "salary": 80000},
    {"name": "Zara", "age": 25, "salary": 90000}, 
]



Step 2 Age → ascending (youngest first)

employees = [
    {"name": "Mike", "age": 25, "salary": 80000},
    {"name": "Zara", "age": 25, "salary": 90000}, 
    {"name": "Alex", "age": 30, "salary": 90000},
    {"name": "Bob", "age": 30, "salary": 80000},
]




Step 3  Salary → descending (highest salary first)

# Our Output 

employees = [
    {"name": "Zara", "age": 25, "salary": 90000}, 
    {"name": "Alex", "age": 30, "salary": 90000},
     {"name": "Mike", "age": 25, "salary": 80000},
    {"name": "Bob", "age": 30, "salary": 80000},
]


# Expected Output

[
    {"name": "Zara", "age": 25, "salary": 90000},  # Salary 90k, youngest in 90k group
    {"name": "Alex", "age": 30, "salary": 90000},  # Same salary, older
    {"name": "Mike", "age": 25, "salary": 80000},  # Salary 80k, youngest in 80k group
    {"name": "Bob", "age": 30, "salary": 80000},   # Same salary, older
]
Python

Code


employees.sort(key=lambda x:x["name"])
employees.sort(key=lambda x:x["age"])
employees.sort(key=lambda x:x["salary"],reverse=True)


# Output

[
  {'name': 'Zara', 'age': 25, 'salary': 90000}, 
  {'name': 'Alex', 'age': 30, 'salary': 90000}, 
  {'name': 'Mike', 'age': 25, 'salary': 80000},
  {'name': 'Bob', 'age': 30, 'salary': 80000}
]
Python

When sorting by multiple columns, apply the last rule first and first rule last, to preserve priority.

Leave a Comment