0
# Sequence Utilities
1
2
Functions specifically for working with sequences and sequence-like objects.
3
4
## Capabilities
5
6
### Type Conversion and Validation
7
8
Functions for ensuring inputs are in expected formats.
9
10
```python { .api }
11
def always_iterable(obj: Any, base_type: type = (str, bytes)) -> Iterable[Any]: ...
12
def always_reversible(iterable: Iterable[Any]) -> Reversible[Any]: ...
13
```
14
15
**Usage:**
16
17
```python
18
from more_itertools import always_iterable, always_reversible
19
20
# Ensure object is always iterable
21
always_iterable(42) # [42]
22
always_iterable([1, 2]) # [1, 2]
23
always_iterable("hello") # ["hello"] (string treated as single item)
24
25
# Ensure object is reversible
26
rev = always_reversible([1, 2, 3])
27
list(reversed(rev)) # [3, 2, 1]
28
```
29
30
### Sequence Properties and Analysis
31
32
Functions for analyzing sequence characteristics.
33
34
```python { .api }
35
def adjacent(iterable: Iterable[Any], predicate: Callable[[Any, Any], bool]) -> bool: ...
36
def is_sorted(iterable: Iterable[Any], *, key: Callable[[Any], Any] = None, reverse: bool = False, strict: bool = False) -> bool: ...
37
def longest_common_prefix(iterables: Iterable[Iterable[Any]]) -> list[Any]: ...
38
```
39
40
**Usage:**
41
42
```python
43
from more_itertools import adjacent, is_sorted, longest_common_prefix
44
45
# Check if any adjacent elements satisfy predicate
46
adjacent([1, 2, 3, 5], lambda a, b: b - a > 1) # True (3, 5)
47
48
# Check if sequence is sorted
49
is_sorted([1, 2, 3, 4]) # True
50
is_sorted([1, 3, 2, 4]) # False
51
is_sorted([4, 3, 2, 1], reverse=True) # True
52
53
# Find common prefix across multiple sequences
54
longest_common_prefix([
55
[1, 2, 3, 4],
56
[1, 2, 5, 6],
57
[1, 2, 7, 8]
58
]) # [1, 2]
59
```
60
61
### Sequence Marking and Annotation
62
63
Functions for marking special positions in sequences.
64
65
```python { .api }
66
def mark_ends(iterable: Iterable[Any]) -> Iterator[tuple[bool, bool, Any]]: ...
67
```
68
69
**Usage:**
70
71
```python
72
from more_itertools import mark_ends
73
74
# Mark first and last elements
75
data = ['a', 'b', 'c', 'd']
76
marked = list(mark_ends(data))
77
# [(True, False, 'a'), (False, False, 'b'), (False, False, 'c'), (False, True, 'd')]
78
# (is_first, is_last, value)
79
```
80
81
### Element Replacement and Modification
82
83
Functions for modifying sequence elements.
84
85
```python { .api }
86
def replace(iterable: Iterable[Any], pred: Callable[[Any], bool], substitutes: Iterable[Any], *, count: int = None, window_size: int = 1) -> Iterator[Any]: ...
87
```
88
89
**Usage:**
90
91
```python
92
from more_itertools import replace
93
94
# Replace elements matching predicate
95
data = [1, 2, 3, 2, 4, 2, 5]
96
result = list(replace(data, lambda x: x == 2, [10, 20]))
97
# [1, 10, 20, 3, 10, 20, 4, 10, 20, 5]
98
99
# Limit number of replacements
100
result = list(replace(data, lambda x: x == 2, [99], count=2))
101
# [1, 99, 3, 99, 4, 2, 5]
102
```
103
104
### Sequence Trimming
105
106
Functions for removing elements from sequence ends.
107
108
```python { .api }
109
def strip(iterable: Iterable[Any], pred: Callable[[Any], bool]) -> Iterator[Any]: ...
110
def lstrip(iterable: Iterable[Any], pred: Callable[[Any], bool]) -> Iterator[Any]: ...
111
def rstrip(iterable: Iterable[Any], pred: Callable[[Any], bool]) -> Iterator[Any]: ...
112
```
113
114
**Usage:**
115
116
```python
117
from more_itertools import strip, lstrip, rstrip
118
119
data = [0, 0, 1, 2, 3, 0, 0]
120
121
# Strip from both ends
122
list(strip(data, lambda x: x == 0)) # [1, 2, 3]
123
124
# Strip from left only
125
list(lstrip(data, lambda x: x == 0)) # [1, 2, 3, 0, 0]
126
127
# Strip from right only
128
list(rstrip(data, lambda x: x == 0)) # [0, 0, 1, 2, 3]
129
```
130
131
### Multi-Sequence Operations
132
133
Functions for operating on multiple sequences together.
134
135
```python { .api }
136
def sort_together(iterables: Iterable[Iterable[Any]], *, key_list: list[Callable[[Any], Any]] = None, reverse: bool = False) -> list[tuple[Any, ...]]: ...
137
```
138
139
**Usage:**
140
141
```python
142
from more_itertools import sort_together
143
144
# Sort multiple sequences based on first sequence
145
names = ['Alice', 'Bob', 'Charlie']
146
ages = [25, 30, 20]
147
scores = [85, 90, 95]
148
149
sorted_data = sort_together([names, ages, scores])
150
# [('Alice', 25, 85), ('Bob', 30, 90), ('Charlie', 20, 95)]
151
152
# Sort by ages (second sequence)
153
sorted_by_age = sort_together([names, ages, scores], key_list=[None, lambda x: x, None])
154
```
155
156
### Sequence Views
157
158
Classes for creating views of sequences.
159
160
```python { .api }
161
class SequenceView:
162
def __init__(self, target: Sequence[Any]) -> None: ...
163
def __getitem__(self, index: int | slice) -> Any: ...
164
def __len__(self) -> int: ...
165
```
166
167
**Usage:**
168
169
```python
170
from more_itertools import SequenceView
171
172
# Create a view of a sequence
173
data = [1, 2, 3, 4, 5]
174
view = SequenceView(data)
175
176
# View behaves like the original sequence
177
view[0] # 1
178
view[1:3] # [2, 3]
179
len(view) # 5
180
181
# But changes to original are reflected
182
data.append(6)
183
len(view) # 6
184
```