Skip to content

Commit 7827ede

Browse files
author
Vitor Serpa
committed
PERF: Use list comprehension to join strings (#41753)
1 parent 1ff6970 commit 7827ede

35 files changed

+74
-69
lines changed

asv_bench/benchmarks/io/csv.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,11 @@ class ReadCSVFloatPrecision(StringIORewind):
291291

292292
def setup(self, sep, decimal, float_precision):
293293
floats = [
294-
"".join(random.choice(string.digits) for _ in range(28)) for _ in range(15)
294+
"".join(
295+
[
296+
random.choice(string.digits) for _ in range(28)
297+
]
298+
) for _ in range(15)
295299
]
296300
rows = sep.join([f"0{decimal}" + "{}"] * 3) + "\n"
297301
data = rows * 5
@@ -395,7 +399,7 @@ class ReadCSVCachedParseDates(StringIORewind):
395399
param_names = ["do_cache", "engine"]
396400

397401
def setup(self, do_cache, engine):
398-
data = ("\n".join(f"10/{year}" for year in range(2000, 2100)) + "\n") * 10
402+
data = ("\n".join([f"10/{year}" for year in range(2000, 2100)]) + "\n") * 10
399403
self.StringIO_input = StringIO(data)
400404

401405
def time_read_csv_cached(self, do_cache, engine):

doc/source/user_guide/io.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5689,7 +5689,7 @@ Example of a callable using PostgreSQL `COPY clause
56895689
writer.writerows(data_iter)
56905690
s_buf.seek(0)
56915691

5692-
columns = ', '.join('"{}"'.format(k) for k in keys)
5692+
columns = ', '.join(['"{}"'.format(k) for k in keys])
56935693
if table.schema:
56945694
table_name = '{}.{}'.format(table.schema, table.name)
56955695
else:

pandas/_config/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ def _describe_option(pat: str = "", _print_desc: bool = True):
157157
if len(keys) == 0:
158158
raise OptionError("No such keys(s)")
159159

160-
s = "\n".join(_build_option_description(k) for k in keys)
160+
s = "\n".join([_build_option_description(k) for k in keys])
161161

162162
if _print_desc:
163163
print(s)

pandas/core/computation/engines.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def _check_ne_builtin_clash(expr: Expr) -> None:
3737
overlap = names & _ne_builtins
3838

3939
if overlap:
40-
s = ", ".join(repr(x) for x in overlap)
40+
s = ", ".join([repr(x) for x in overlap])
4141
raise NumExprClobberingError(
4242
f'Variables in expression "{expr}" overlap with builtins: ({s})'
4343
)

pandas/core/computation/parsing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def create_valid_python_identifier(name: str) -> str:
5757
}
5858
)
5959

60-
name = "".join(special_characters_replacements.get(char, char) for char in name)
60+
name = "".join([special_characters_replacements.get(char, char) for char in name])
6161
name = "BACKTICK_QUOTED_STRING_" + name
6262

6363
if not name.isidentifier():

pandas/core/computation/pytables.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ def __init__(
579579
else:
580580
w = _validate_where(w)
581581
where[idx] = w
582-
_where = " & ".join(f"({w})" for w in com.flatten(where))
582+
_where = " & ".join([f"({w})" for w in com.flatten(where)])
583583
else:
584584
# _validate_where ensures we otherwise have a string
585585
_where = where

pandas/core/computation/scope.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def _raw_hex_id(obj) -> str:
5050
"""Return the padded hexadecimal id of ``obj``."""
5151
# interpret as a pointer since that's what really what id returns
5252
packed = struct.pack("@P", id(obj))
53-
return "".join(_replacer(x) for x in packed)
53+
return "".join([_replacer(x) for x in packed])
5454

5555

5656
DEFAULT_GLOBALS = {

pandas/core/generic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11036,7 +11036,7 @@ def last_valid_index(self) -> Hashable | None:
1103611036
def _doc_params(cls):
1103711037
"""Return a tuple of the doc params."""
1103811038
axis_descr = (
11039-
f"{{{', '.join(f'{a} ({i})' for i, a in enumerate(cls._AXIS_ORDERS))}}}"
11039+
f"{{{', '.join([f'{a} ({i})' for i, a in enumerate(cls._AXIS_ORDERS)])}}}"
1104011040
)
1104111041
name = cls._constructor_sliced.__name__ if cls._AXIS_LEN > 1 else "scalar"
1104211042
name2 = cls.__name__

pandas/core/internals/blocks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ def __repr__(self) -> str:
281281
result = f"{name}: {len(self)} dtype: {self.dtype}"
282282
else:
283283

284-
shape = " x ".join(str(s) for s in self.shape)
284+
shape = " x ".join([str(s) for s in self.shape])
285285
result = f"{name}: {self.mgr_locs.indexer}, {shape}, dtype: {self.dtype}"
286286

287287
return result

pandas/io/formats/excel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,7 @@ def _generate_body(self, coloffset: int) -> Iterable[ExcelCell]:
769769
series = self.df.iloc[:, colidx]
770770
for i, val in enumerate(series):
771771
if styles is not None:
772-
css = ";".join(a + ":" + str(v) for (a, v) in styles[i, colidx])
772+
css = ";".join([a + ":" + str(v) for (a, v) in styles[i, colidx]])
773773
xlstyle = self.style_converter(css)
774774
yield ExcelCell(self.rowcounter + i, colidx + coloffset, val, xlstyle)
775775

pandas/io/formats/latex.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ def get_result(self) -> str:
358358
self.bottom_separator,
359359
self.env_end,
360360
]
361-
result = "\n".join(item for item in elements if item)
361+
result = "\n".join([item for item in elements if item])
362362
trailing_newline = "\n"
363363
result += trailing_newline
364364
return result
@@ -527,13 +527,13 @@ def env_begin(self) -> str:
527527
f"\\begin{{longtable}}{self._position_macro}{{{self.column_format}}}"
528528
)
529529
elements = [first_row, f"{self._caption_and_label()}"]
530-
return "\n".join(item for item in elements if item)
530+
return "\n".join([item for item in elements if item])
531531

532532
def _caption_and_label(self) -> str:
533533
if self.caption or self.label:
534534
double_backslash = "\\\\"
535535
elements = [f"{self._caption_macro}", f"{self._label_macro}"]
536-
caption_and_label = "\n".join(item for item in elements if item)
536+
caption_and_label = "\n".join([item for item in elements if item])
537537
caption_and_label += double_backslash
538538
return caption_and_label
539539
else:
@@ -611,7 +611,7 @@ def env_begin(self) -> str:
611611
f"{self._label_macro}",
612612
f"\\begin{{tabular}}{{{self.column_format}}}",
613613
]
614-
return "\n".join(item for item in elements if item)
614+
return "\n".join([item for item in elements if item])
615615

616616
@property
617617
def bottom_separator(self) -> str:

pandas/io/formats/style.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2018,7 +2018,7 @@ def set_properties(self, subset: Subset | None = None, **kwargs) -> Styler:
20182018
>>> df.style.set_properties(color="white", align="right")
20192019
>>> df.style.set_properties(**{'background-color': 'yellow'})
20202020
"""
2021-
values = "".join(f"{p}: {v};" for p, v in kwargs.items())
2021+
values = "".join([f"{p}: {v};" for p, v in kwargs.items()])
20222022
return self.applymap(lambda x: values, subset=subset)
20232023

20242024
@staticmethod

pandas/io/formats/xml.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,9 @@ def build_attribs(self) -> None:
357357
flat_col = col
358358
if isinstance(col, tuple):
359359
flat_col = (
360-
"".join(str(c) for c in col).strip()
360+
"".join([str(c) for c in col]).strip()
361361
if "" in col
362-
else "_".join(str(c) for c in col).strip()
362+
else "_".join([str(c) for c in col]).strip()
363363
)
364364

365365
attr_name = f"{self.prefix_uri}{flat_col}"
@@ -384,9 +384,9 @@ def build_elems(self) -> None:
384384
flat_col = col
385385
if isinstance(col, tuple):
386386
flat_col = (
387-
"".join(str(c) for c in col).strip()
387+
"".join([str(c) for c in col]).strip()
388388
if "" in col
389-
else "_".join(str(c) for c in col).strip()
389+
else "_".join([str(c) for c in col]).strip()
390390
)
391391

392392
elem_name = f"{self.prefix_uri}{flat_col}"
@@ -529,9 +529,9 @@ def build_attribs(self) -> None:
529529
flat_col = col
530530
if isinstance(col, tuple):
531531
flat_col = (
532-
"".join(str(c) for c in col).strip()
532+
"".join([str(c) for c in col]).strip()
533533
if "" in col
534-
else "_".join(str(c) for c in col).strip()
534+
else "_".join([str(c) for c in col]).strip()
535535
)
536536

537537
attr_name = f"{self.prefix_uri}{flat_col}"
@@ -556,9 +556,9 @@ def build_elems(self) -> None:
556556
flat_col = col
557557
if isinstance(col, tuple):
558558
flat_col = (
559-
"".join(str(c) for c in col).strip()
559+
"".join([str(c) for c in col]).strip()
560560
if "" in col
561-
else "_".join(str(c) for c in col).strip()
561+
else "_".join([str(c) for c in col]).strip()
562562
)
563563

564564
elem_name = f"{self.prefix_uri}{flat_col}"

pandas/io/html.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ def _build_xpath_expr(attrs) -> str:
627627
if "class_" in attrs:
628628
attrs["class"] = attrs.pop("class_")
629629

630-
s = " and ".join(f"@{k}={repr(v)}" for k, v in attrs.items())
630+
s = " and ".join([f"@{k}={repr(v)}" for k, v in attrs.items()])
631631
return f"[{s}]"
632632

633633

@@ -861,7 +861,7 @@ def _parser_dispatch(flavor):
861861

862862

863863
def _print_as_set(s) -> str:
864-
arg = ", ".join(pprint_thing(el) for el in s)
864+
arg = ", ".join([pprint_thing(el) for el in s])
865865
return f"{{{arg}}}"
866866

867867

pandas/io/parsers/base_parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ def extract(r):
351351
# level, then our header was too long.
352352
for n in range(len(columns[0])):
353353
if all(ensure_str(col[n]) in self.unnamed_cols for col in columns):
354-
header = ",".join(str(x) for x in self.header)
354+
header = ",".join([str(x) for x in self.header])
355355
raise ParserError(
356356
f"Passed header=[{header}] are too many rows "
357357
"for this multi_index of columns"
@@ -1138,7 +1138,7 @@ def _try_convert_dates(parser: Callable, colspec, data_dict, columns):
11381138
else:
11391139
colnames.append(c)
11401140

1141-
new_name = "_".join(str(x) for x in colnames)
1141+
new_name = "_".join([str(x) for x in colnames])
11421142
to_parse = [data_dict[c] for c in colnames if c in data_dict]
11431143

11441144
new_col = parser(*to_parse)

pandas/io/parsers/python_parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1159,7 +1159,7 @@ def get_rows(self, infer_nrows, skiprows=None):
11591159

11601160
def detect_colspecs(self, infer_nrows=100, skiprows=None):
11611161
# Regex escape the delimiters
1162-
delimiters = "".join(fr"\{x}" for x in self.delimiter)
1162+
delimiters = "".join([fr"\{x}" for x in self.delimiter])
11631163
pattern = re.compile(f"([^{delimiters}]+)")
11641164
rows = self.get_rows(infer_nrows, skiprows)
11651165
if not rows:

pandas/io/pytables.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2642,7 +2642,7 @@ def __repr__(self) -> str:
26422642
s = self.shape
26432643
if s is not None:
26442644
if isinstance(s, (list, tuple)):
2645-
jshape = ",".join(pprint_thing(x) for x in s)
2645+
jshape = ",".join([pprint_thing(x) for x in s])
26462646
s = f"[{jshape}]"
26472647
return f"{self.pandas_type:12.12} (shape->{s})"
26482648
return self.pandas_type
@@ -3309,10 +3309,10 @@ def __repr__(self) -> str:
33093309

33103310
ver = ""
33113311
if self.is_old_version:
3312-
jver = ".".join(str(x) for x in self.version)
3312+
jver = ".".join([str(x) for x in self.version])
33133313
ver = f"[{jver}]"
33143314

3315-
jindex_axes = ",".join(a.name for a in self.index_axes)
3315+
jindex_axes = ",".join([a.name for a in self.index_axes])
33163316
return (
33173317
f"{self.pandas_type:12.12}{ver} "
33183318
f"(typ->{self.table_type_short},nrows->{self.nrows},"
@@ -3519,7 +3519,7 @@ def validate_version(self, where=None):
35193519
"""are we trying to operate on an old version?"""
35203520
if where is not None:
35213521
if self.version[0] <= 0 and self.version[1] <= 10 and self.version[2] < 1:
3522-
ws = incompatibility_doc % ".".join(str(x) for x in self.version)
3522+
ws = incompatibility_doc % ".".join([str(x) for x in self.version])
35233523
warnings.warn(ws, IncompatibilityWarning)
35243524

35253525
def validate_min_itemsize(self, min_itemsize):
@@ -4066,7 +4066,7 @@ def get_blk_items(mgr):
40664066
new_blocks.append(b)
40674067
new_blk_items.append(b_items)
40684068
except (IndexError, KeyError) as err:
4069-
jitems = ",".join(pprint_thing(item) for item in items)
4069+
jitems = ",".join([pprint_thing(item) for item in items])
40704070
raise ValueError(
40714071
f"cannot match existing table structure for [{jitems}] "
40724072
"on appending data"

pandas/io/sql.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1913,7 +1913,7 @@ def insert_statement(self, *, num_rows: int):
19131913
col_names = ",".join(bracketed_names)
19141914

19151915
row_wildcards = ",".join([wld] * len(names))
1916-
wildcards = ",".join(f"({row_wildcards})" for _ in range(num_rows))
1916+
wildcards = ",".join([f"({row_wildcards})" for _ in range(num_rows)])
19171917
insert_statement = (
19181918
f"INSERT INTO {escape(self.name)} ({col_names}) VALUES {wildcards}"
19191919
)
@@ -1952,7 +1952,7 @@ def _create_table_setup(self):
19521952
keys = [self.keys]
19531953
else:
19541954
keys = self.keys
1955-
cnames_br = ", ".join(escape(c) for c in keys)
1955+
cnames_br = ", ".join([escape(c) for c in keys])
19561956
create_tbl_stmts.append(
19571957
f"CONSTRAINT {self.name}_pk PRIMARY KEY ({cnames_br})"
19581958
)
@@ -1972,7 +1972,7 @@ def _create_table_setup(self):
19721972
ix_cols = [cname for cname, _, is_index in column_names_and_types if is_index]
19731973
if len(ix_cols):
19741974
cnames = "_".join(ix_cols)
1975-
cnames_br = ",".join(escape(c) for c in ix_cols)
1975+
cnames_br = ",".join([escape(c) for c in ix_cols])
19761976
create_stmts.append(
19771977
"CREATE INDEX "
19781978
+ escape("ix_" + self.name + "_" + cnames)

pandas/io/stata.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,12 +1357,12 @@ def _read_old_header(self, first_char: bytes) -> None:
13571357
try:
13581358
self.typlist = [self.TYPE_MAP[typ] for typ in typlist]
13591359
except ValueError as err:
1360-
invalid_types = ",".join(str(x) for x in typlist)
1360+
invalid_types = ",".join([str(x) for x in typlist])
13611361
raise ValueError(f"cannot convert stata types [{invalid_types}]") from err
13621362
try:
13631363
self.dtyplist = [self.DTYPE_MAP[typ] for typ in typlist]
13641364
except ValueError as err:
1365-
invalid_dtypes = ",".join(str(x) for x in typlist)
1365+
invalid_dtypes = ",".join([str(x) for x in typlist])
13661366
raise ValueError(f"cannot convert stata dtypes [{invalid_dtypes}]") from err
13671367

13681368
if self.format_version > 108:

pandas/plotting/_core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -866,7 +866,7 @@ def _get_call_args(backend_name, data, args, kwargs):
866866
if args and isinstance(data, ABCSeries):
867867
positional_args = str(args)[1:-1]
868868
keyword_args = ", ".join(
869-
f"{name}={repr(value)}" for (name, _), value in zip(arg_def, args)
869+
[f"{name}={repr(value)}" for (name, _), value in zip(arg_def, args)]
870870
)
871871
msg = (
872872
"`Series.plot()` should not be called with positional "

pandas/plotting/_matplotlib/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@ def _get_index_name(self) -> str | None:
714714
if isinstance(self.data.index, ABCMultiIndex):
715715
name = self.data.index.names
716716
if com.any_not_none(*name):
717-
name = ",".join(pprint_thing(x) for x in name)
717+
name = ",".join([pprint_thing(x) for x in name])
718718
else:
719719
name = None
720720
else:

pandas/tests/generic/test_frame.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def finalize(self, other, method=None, **kwargs):
126126
for name in self._metadata:
127127
if method == "concat":
128128
value = "+".join(
129-
getattr(o, name) for o in other.objs if getattr(o, name, None)
129+
[getattr(o, name) for o in other.objs if getattr(o, name, None)]
130130
)
131131
object.__setattr__(self, name, value)
132132
else:

pandas/tests/generic/test_series.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def finalize(self, other, method=None, **kwargs):
130130
for name in self._metadata:
131131
if method == "concat" and name == "filename":
132132
value = "+".join(
133-
getattr(o, name) for o in other.objs if getattr(o, name, None)
133+
[getattr(o, name) for o in other.objs if getattr(o, name, None)]
134134
)
135135
object.__setattr__(self, name, value)
136136
else:

pandas/tests/indexes/period/test_indexing.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -513,11 +513,10 @@ def test_get_indexer_mismatched_dtype_with_method(self, non_comparable_idx, meth
513513
continue
514514
# Two different error message patterns depending on dtypes
515515
msg = "|".join(
516-
re.escape(msg)
517-
for msg in (
516+
[re.escape(msg) for msg in (
518517
f"Cannot compare dtypes {pi.dtype} and {other.dtype}",
519518
" not supported between instances of ",
520-
)
519+
)]
521520
)
522521
with pytest.raises(TypeError, match=msg):
523522
pi.get_indexer(other2, method=method)

pandas/tests/io/formats/style/test_align.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def bar_grad(a=None, b=None, c=None, d=None):
1313
return ret + [
1414
(
1515
"background",
16-
f"linear-gradient(90deg,{','.join(x for x in [a, b, c, d] if x)})",
16+
f"linear-gradient(90deg,{','.join([x for x in [a, b, c, d] if x])})",
1717
)
1818
]
1919

pandas/tests/io/formats/test_format.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1369,7 +1369,7 @@ def test_to_string(self):
13691369
)
13701370
lines = result.split("\n")
13711371
header = lines[0].strip().split()
1372-
joined = "\n".join(re.sub(r"\s+", " ", x).strip() for x in lines[1:])
1372+
joined = "\n".join([re.sub(r"\s+", " ", x).strip() for x in lines[1:]])
13731373
recons = read_csv(StringIO(joined), names=header, header=None, sep=" ")
13741374
tm.assert_series_equal(recons["B"], biggie["B"])
13751375
assert recons["A"].count() == biggie["A"].count()

0 commit comments

Comments
 (0)