Python Strings
Tags: python, programming, beginners, tutorial
Published: 2024-06-27 11:52:20

### Strings in Python

Strings in Python are a sequence of characters enclosed within single quotes (`'`), double quotes (`"`), triple single quotes (`'''`), or triple double quotes (`"""`). They are immutable, meaning once a string is created, it cannot be changed.

#### Basic String Creation

```python
single_quote_str = 'Hello, World!'
double_quote_str = "Hello, World!"
triple_single_quote_str = '''Hello,
World!'''
triple_double_quote_str = """Hello,
World!"""
```

#### String Immutability

Once a string is created, you cannot change its individual characters.

```python
s = "hello"
# s[0] = 'H'  # This will raise a TypeError
```

#### String Concatenation

You can concatenate strings using the `+` operator.

```python
s1 = "Hello"
s2 = "World"
s3 = s1 + " " + s2  # "Hello World"
```

#### String Repetition

You can repeat strings using the `*` operator.

```python
s = "Hello"
s2 = s * 3  # "HelloHelloHello"
```

#### Accessing Characters

You can access characters in a string using indexing.

```python
s = "Hello, World!"
char = s[0]        # 'H'
```

Negative indexing can also be used to access characters from the end.

```python
last_char = s[-1]  # '!'
```

#### Slicing Strings

Slicing allows you to get a substring from a string.

```python
s = "Hello, World!"
substring = s[0:5]  # 'Hello'
substring = s[:5]   # 'Hello'
substring = s[7:]   # 'World!'
substring = s[::2]  # 'Hlo ol!'
```

#### String Length

You can get the length of a string using the `len()` function.

```python
s = "Hello, World!"
length = len(s)  # 13
```

#### Escape Characters

Escape characters allow you to include special characters in strings.

```python
newline = "Hello\nWorld!"       # Newline
tab = "Hello\tWorld!"           # Tab
quote = "He said, \"Hello!\""   # Double quote
backslash = "This is a backslash: \\"  # Backslash
```

#### Raw Strings

Raw strings treat backslashes as literal characters.

```python
raw_str = r"C:\Users\name"  # "C:\\Users\\name"
```

#### String Membership

You can check if a substring exists within a string using the `in` and `not in` operators.

```python
s = "Hello, World!"
result = "Hello" in s    # True
result = "Hi" not in s   # True
```

#### Iterating Through Strings

You can iterate through a string using a `for` loop.

```python
s = "Hello"
for char in s:
    print(char)
```

### String Comparison in Python

String comparison in Python is used to determine the relative order of two strings or to check for equality. Python uses lexicographical order to compare strings, meaning that strings are compared based on the order of their characters in the Unicode code point sequence.

#### Comparison Operators

Python provides several comparison operators that can be used to compare strings:

- `==`: Equal
- `!=`: Not equal
- `<`: Less than
- `<=`: Less than or equal to
- `>`: Greater than
- `>=`: Greater than or equal to

#### Lexicographical Order

When comparing strings lexicographically, Python compares character by character, starting from the first character of each string, using their Unicode code points.

1. **Equal (`==`) and Not Equal (`!=`)**

```python
s1 = "apple"
s2 = "apple"
s3 = "banana"

print(s1 == s2)  # True
print(s1 == s3)  # False
print(s1 != s3)  # True
```

2. **Less Than (`<`), Less Than or Equal To (`<=`)**

```python
s1 = "apple"
s2 = "banana"

print(s1 < s2)   # True, because 'a' < 'b'
print(s1 <= s2)  # True, because 'a' < 'b'
```

3. **Greater Than (`>`), Greater Than or Equal To (`>=`)**

```python
s1 = "banana"
s2 = "apple"

print(s1 > s2)   # True, because 'b' > 'a'
print(s1 >= s2)  # True, because 'b' > 'a'
```

#### Case Sensitivity

String comparison in Python is case-sensitive, meaning uppercase and lowercase letters are treated as different characters with different Unicode code points.

```python
s1 = "Apple"
s2 = "apple"

print(s1 == s2)  # False, because 'A' != 'a'
print(s1 < s2)   # True, because 'A' < 'a' in Unicode
print(s1 > s2)   # False, because 'A' < 'a' in Unicode
```

#### Unicode Code Points

Python compares strings based on Unicode code points. You can use the `ord()` function to get the Unicode code point of a character.

```python
print(ord('a'))  # 97
print(ord('A'))  # 65
```

#### Comparing Strings of Different Lengths

When comparing strings of different lengths, Python compares each character in order until it reaches the end of one of the strings. If the compared characters are equal up to that point, the shorter string is considered less than the longer string.

```python
s1 = "apple"
s2 = "apples"

print(s1 < s2)   # True, because 'apple' is shorter than 'apples'
print(s1 > s2)   # False, because 'apple' is shorter than 'apples'
```

#### Practical Examples

1. **Using Comparison in Conditional Statements**

```python
password = "Secret123"
user_input = "secret123"

if user_input == password:
    print("Access granted")
else:
    print("Access denied")  # Output: Access denied (case-sensitive comparison)
```

2. **Case-Insensitive Comparison**

To perform a case-insensitive comparison, you can convert both strings to the same case (e.g., lower or upper) before comparing them.

```python
s1 = "Apple"
s2 = "apple"

print(s1.lower() == s2.lower())  # True
print(s1.upper() == s2.upper())  # True
```

### String Formatting in Python

String formatting is a powerful feature in Python that allows you to create complex strings with dynamic content. Python provides several ways to format strings, each with its own use cases and benefits. Here, we'll cover:

1. **Old-style formatting (`%` operator)**
2. **`str.format()` method**
3. **Formatted string literals (f-strings)**

#### 1. Old-style Formatting (`%` operator)

Old-style formatting uses the `%` operator to insert values into a string. This method is similar to the C-style `printf`.

```python
name = "Alice"
age = 30
formatted_str = "Name: %s, Age: %d" % (name, age)
print(formatted_str)  # Output: Name: Alice, Age: 30
```

**Format Specifiers:**

- `%s`: String
- `%d`: Integer
- `%f`: Floating-point number
- `%x`: Hexadecimal
- `%%`: Literal `%` character

```python
value = 12.3456
formatted_str = "Value: %.2f" % value  # Output: Value: 12.35
```

#### 2. `str.format()` Method

The `str.format()` method is more powerful and flexible than the old-style `%` operator. It uses curly braces `{}` as placeholders within the string.

```python
name = "Alice"
age = 30
formatted_str = "Name: {}, Age: {}".format(name, age)
print(formatted_str)  # Output: Name: Alice, Age: 30
```

**Positional and Keyword Arguments:**

You can use positional and keyword arguments to specify values.

```python
# Positional arguments
formatted_str = "Name: {0}, Age: {1}".format(name, age)

# Keyword arguments
formatted_str = "Name: {name}, Age: {age}".format(name="Alice", age=30)
```

**Reusing Arguments:**

Arguments can be reused in the format string.

```python
formatted_str = "Name: {0}, Age: {1}, Again Name: {0}".format(name, age)
```

**Format Specifiers:**

- `{:.2f}`: Floating-point number with 2 decimal places
- `{:,}`: Number with thousands separator
- `{:<10}`: Left-align within 10 spaces
- `{:>10}`: Right-align within 10 spaces
- `{:^10}`: Center-align within 10 spaces

```python
value = 12345.6789
formatted_str = "Value: {:.2f}".format(value)   # Output: Value: 12345.68
formatted_str = "Value: {:,}".format(value)     # Output: Value: 12,345.6789
formatted_str = "Value: {:<10}".format(value)   # Output: Value: 12345.6789 
formatted_str = "Value: {:>10}".format(value)   # Output: Value: 12345.6789
formatted_str = "Value: {:^10}".format(value)   # Output: Value: 12345.6789
```

#### 3. Formatted String Literals (F-strings)

F-strings (formatted string literals), introduced in Python 3.6, provide a concise and readable way to embed expressions inside string literals using curly braces `{}`.

```python
name = "Alice"
age = 30
formatted_str = f"Name: {name}, Age: {age}"
print(formatted_str)  # Output: Name: Alice, Age: 30
```

**Expression Evaluation:**

F-strings allow the inclusion of expressions inside the curly braces.

```python
a = 5
b = 10
formatted_str = f"Sum: {a + b}"
print(formatted_str)  # Output: Sum: 15
```

**Format Specifiers:**

F-strings support the same format specifiers as `str.format()`.

```python
value = 12345.6789
formatted_str = f"Value: {value:.2f}"   # Output: Value: 12345.68
formatted_str = f"Value: {value:,}"     # Output: Value: 12,345.6789
formatted_str = f"Value: {value:<10}"   # Output: Value: 12345.6789 
formatted_str = f"Value: {value:>10}"   # Output: Value: 12345.6789
formatted_str = f"Value: {value:^10}"   # Output: Value: 12345.6789
```

**Multi-line F-strings:**

F-strings can span multiple lines using triple quotes.

```python
name = "Alice"
age = 30
formatted_str = f"""
Name: {name}
Age: {age}
"""
print(formatted_str)
```

### Advanced Formatting

#### Nested Formatting

You can nest formatting expressions for complex formatting scenarios.

```python
width = 10
precision = 2
value = 12.34567
formatted_str = f"Value: {value:{width}.{precision}f}"  # Output: Value:      12.35
```

### String Methods in Python

#### Capitalization and Case Conversion

**`capitalize()`**
- Converts the first character of the string to uppercase.
- **Syntax:** `str.capitalize()`

```python
s = "hello"
print(s.capitalize())  # Output: "Hello"
```

**`lower()`**
- Converts all characters of the string to lowercase.
- **Syntax:** `str.lower()`

```python
s = "HELLO"
print(s.lower())  # Output: "hello"
```

**`upper()`**
- Converts all characters of the string to uppercase.
- **Syntax:** `str.upper()`

```python
s = "hello"
print(s.upper())  # Output: "HELLO"
```

**`islower()`**
- Checks if all characters in the string are lowercase.
- **Syntax:** `str.islower()`

```python
s = "hello"
print(s.islower())  # Output: True
```

**`isupper()`**
- Checks if all characters in the string are uppercase.
- **Syntax:** `str.isupper()`

```python
s = "HELLO"
print(s.isupper())  # Output: True
```

#### Alignment and Filling

**`center()`**
- Centers the string within a specified width, padding with spaces or a specified character.
- **Syntax:** `str.center(width, fillchar)`

```python
s = "hello"
print(s.center(10))          # Output: "  hello   "
print(s.center(10, '*'))     # Output: "**hello***"
```

**`lstrip()`**
- Removes leading whitespace or specified characters.
- **Syntax:** `str.lstrip([chars])`

```python
s = "  hello  "
print(s.lstrip())            # Output: "hello  "
s = "***hello***"
print(s.lstrip('*'))         # Output: "hello***"
```

**`rstrip()`**
- Removes trailing whitespace or specified characters.
- **Syntax:** `str.rstrip([chars])`

```python
s = "  hello  "
print(s.rstrip())            # Output: "  hello"
s = "***hello***"
print(s.rstrip('*'))         # Output: "***hello"
```

**`strip()`**
- Removes leading and trailing whitespace or specified characters.
- **Syntax:** `str.strip([chars])`

```python
s = "  hello  "
print(s.strip())             # Output: "hello"
s = "***hello***"
print(s.strip('*'))          # Output: "hello"
```

#### Searching and Counting

**`count()`**
- Counts occurrences of a substring in the string.
- **Syntax:** `str.count(sub[, start[, end]])`

```python
s = "hello hello"
print(s.count("hello"))      # Output: 2
```

**`endswith()`**
- Checks if the string ends with a specified suffix.
- **Syntax:** `str.endswith(suffix[, start[, end]])`

```python
s = "hello"
print(s.endswith("lo"))      # Output: True
```

**`find()`**
- Finds the first occurrence of a substring. Returns -1 if not found.
- **Syntax:** `str.find(sub[, start[, end]])`

```python
s = "hello"
print(s.find("e"))           # Output: 1
print(s.find("a"))           # Output: -1
```

**`index()`**
- Finds the first occurrence of a substring. Raises a ValueError if not found.
- **Syntax:** `str.index(sub[, start[, end]])`

```python
s = "hello"
print(s.index("e"))          # Output: 1
# print(s.index("a"))        # Raises ValueError
```

**`rfind()`**
- Finds the last occurrence of a substring. Returns -1 if not found.
- **Syntax:** `str.rfind(sub[, start[, end]])`

```python
s = "hello hello"
print(s.rfind("hello"))      # Output: 6
```

**`rindex()`**
- Finds the last occurrence of a substring. Raises a ValueError if not found.
- **Syntax:** `str.rindex(sub[, start[, end]])`

```python
s = "hello hello"
print(s.rindex("hello"))     # Output: 6
# print(s.rindex("world"))   # Raises ValueError
```

**`startswith()`**
- Checks if the string starts with a specified prefix.
- **Syntax:** `str.startswith(prefix[, start[, end]])`

```python
s = "hello"
print(s.startswith("he"))    # Output: True
```

#### Type Checking

**`isalnum()`**
- Checks if all characters in the string are alphanumeric.
- **Syntax:** `str.isalnum()`

```python
s = "hello123"
print(s.isalnum())           # Output: True
s = "hello 123"
print(s.isalnum())           # Output: False
```

**`isalpha()`**
- Checks if all characters in the string are alphabetic.
- **Syntax:** `str.isalpha()`

```python
s = "hello"
print(s.isalpha())           # Output: True
s = "hello123"
print(s.isalpha())           # Output: False
```

**`isdecimal()`**
- Checks if all characters in the string are decimal characters.
- **Syntax:** `str.isdecimal()`

```python
s = "123"
print(s.isdecimal())         # Output: True
s = "123.45"
print(s.isdecimal())         # Output: False
```

**`isdigit()`**
- Checks if all characters in the string are digits.
- **Syntax:** `str.isdigit()`

```python
s = "123"
print(s.isdigit())           # Output: True
s = "123.45"
print(s.isdigit())           # Output: False
```

**`isspace()`**
- Checks if all characters in the string are whitespace.
- **Syntax:** `str.isspace()`

```python
s = "   "
print(s.isspace())           # Output: True
s = "  a "
print(s.isspace())           # Output: False
```

#### Joining and Splitting

**`join()`**
- Joins elements of an iterable with the string as a delimiter.
- **Syntax:** `str.join(iterable)`

```python
s = "-"
seq = ["a", "b", "c"]
print(s.join(seq))           # Output: "a-b-c"
```

**`split()`**
- Splits the string at the specified delimiter and returns a list.
- **Syntax:** `str.split(sep[, maxsplit])`

```python
s = "a-b-c"
print(s.split("-"))          # Output: ["a", "b", "c"]
```

#### Replacing

**`replace()`**
- Replaces occurrences of a substring with another substring.
- **Syntax:** `str.replace(old, new[, count])`

```python
s = "hello world"
print(s.replace("world", "there"))  # Output: "hello there"
```

#### Formatting

**`format()`**
- Formats the string using placeholders.
- **Syntax:** `str.format(*args, **kwargs)`

```python
s = "Hello, {}"
print(s.format("Alice"))     # Output: "Hello, Alice"
```