Skip to content

Commit

Permalink
gh-37545: various list-comprehension in combinat (ruff PERF)
Browse files Browse the repository at this point in the history
    
following some `ruff --select=PERF src/sage/combinat` suggestions

i.e. using more often list comprehension where possible

(also turned one method to an iterator)

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [ ] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation accordingly.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - #12345: short description why this is a dependency -->
<!-- - #34567: ... -->
    
URL: #37545
Reported by: Frédéric Chapoton
Reviewer(s): Frédéric Chapoton, Martin Rubey
  • Loading branch information
Release Manager committed Mar 29, 2024
2 parents 4f2428b + 32799a6 commit a145be7
Show file tree
Hide file tree
Showing 13 changed files with 57 additions and 81 deletions.
7 changes: 3 additions & 4 deletions src/sage/combinat/chas/fsym.py
Original file line number Diff line number Diff line change
Expand Up @@ -675,10 +675,9 @@ def product_on_basis(self, t1, t2):
"""
n = t1.size()
m = n + t2.size()
tableaux = []
for t in StandardTableaux(m):
if t.restrict(n) == t1 and standardize(t.anti_restrict(n).rectify()) == t2:
tableaux.append(t)
tableaux = [t for t in StandardTableaux(m)
if t.restrict(n) == t1
and standardize(t.anti_restrict(n).rectify()) == t2]
return self.sum_of_monomials(tableaux)

@cached_method
Expand Down
24 changes: 12 additions & 12 deletions src/sage/combinat/cluster_algebra_quiver/mutation_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def _triangles(dg):
return trians


def _all_induced_cycles_iter( dg ):
def _all_induced_cycles_iter(dg):
"""
Return an iterator for all induced oriented cycles of length
greater than or equal to 4 in the digraph ``dg``.
Expand Down Expand Up @@ -356,9 +356,9 @@ def _connected_mutation_type(dg):
for edge in edges:
label = edge[2]
if label not in [(1,-1),(2,-2),(1,-2),(2,-1),(4,-1),(1,-4)]:
# _false_return(i) is a simple function that simply returns 'unknown'. For debugging purposes, it
# can also output 'DEBUG: error i' if desired.
# this command is used many times in this code, something times without the argument i.
# _false_return(i) is a simple function that simply returns 'unknown'. For debugging purposes, it
# can also output 'DEBUG: error i' if desired.
# this command is used many times in this code, something times without the argument i.
return _false_return(2)
elif label == (2,-2):
dg.set_edge_label( edge[0], edge[1], 1 )
Expand Down Expand Up @@ -1023,17 +1023,17 @@ def _connected_mutation_type_AAtildeD(dg, ret_conn_vert=False):
multiple_trian_edges = list(set(multiple_trian_edges))

# test that there at most three edges appearing in exactly two oriented triangles
count = len( multiple_trian_edges )
count = len(multiple_trian_edges)
if count >= 4:
return _false_return(321)
# if two edges appearing in exactly two oriented triangles, test that the two edges together
# determine a unique triangle
elif count > 1:
test_triangles = []
for edge in multiple_trian_edges:
test_triangles.append([ tuple(trian) for trian in oriented_trians if edge in trian ])
unique_triangle = set(test_triangles[0]).intersection( *test_triangles[1:] )
if len( unique_triangle ) != 1:
test_triangles = [[tuple(trian) for trian in oriented_trians
if edge in trian]
for edge in multiple_trian_edges]
unique_triangle = set.intersection(*map(set, test_triangles))
if len(unique_triangle) != 1:
return _false_return(19)
else:
# if a long_cycle had previously been found, this unique oriented triangle is a second long_cycle, a contradiction.
Expand Down Expand Up @@ -1299,7 +1299,7 @@ def load_data(n, user=True):
return data


def _mutation_type_from_data( n, dig6, compute_if_necessary=True ):
def _mutation_type_from_data(n, dig6, compute_if_necessary=True):
r"""
Return the mutation type from the given dig6 data by looking into
the precomputed mutation types
Expand Down Expand Up @@ -1506,7 +1506,7 @@ def _random_tests(mt, k, mut_class=None, nr_mut=5):
dg = dg_new


def _random_multi_tests( n, k, nr_mut=5 ):
def _random_multi_tests(n, k, nr_mut=5):
"""
Provide multiple random tests to find bugs in the mutation type methods.
Expand Down
5 changes: 1 addition & 4 deletions src/sage/combinat/composition.py
Original file line number Diff line number Diff line change
Expand Up @@ -1417,10 +1417,7 @@ def specht_module(self, base_ring=None):
from sage.rings.rational_field import QQ
base_ring = QQ
R = SymmetricGroupAlgebra(base_ring, sum(self))
cells = []
for i, row in enumerate(self):
for j in range(row):
cells.append((i, j))
cells = [(i, j) for i, row in enumerate(self) for j in range(row)]
return SpechtModule(R, cells)

def specht_module_dimension(self, base_ring=None):
Expand Down
17 changes: 5 additions & 12 deletions src/sage/combinat/designs/covering_design.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,21 +144,14 @@ def trivial_covering_design(v, k, t):
"""
if t == 0: # single block [0, ..., k-1]
blk = []
for i in range(k):
blk.append(i)
blk = list(range(k))
return CoveringDesign(v, k, t, 1, range(v), [blk], 1, "Trivial")
if t == 1: # blocks [0, ..., k-1], [k, ..., 2k-1], ...
size = Rational((v, k)).ceil()
blocks = []
for i in range(size - 1):
blk = []
for j in range(i * k, (i + 1) * k):
blk.append(j)
blocks.append(blk)
blk = [] # last block: if k does not divide v, wrap around
for j in range((size - 1) * k, v):
blk.append(j)
blocks = [list(range(i * k, (i + 1) * k))
for i in range(size - 1)]
# last block: if k does not divide v, wrap around
blk = list(range((size - 1) * k, v))
for j in range(k - len(blk)):
blk.append(j)
blk.sort()
Expand Down
10 changes: 5 additions & 5 deletions src/sage/combinat/designs/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -3663,18 +3663,18 @@ def DM_51_6_1():
[ 34, 32, 36, 26, 20]
]

Mb = [[0,0,0,0,0]]
Mb = [[0, 0, 0, 0, 0]]

for R in zip(*M):
for i in range(5):
for RR in [list(R), [-x for x in R]]:
Mb.append(RR)
R = cyclic_shift(R,1)
Mb.extend([list(R), [-x for x in R]])
R = cyclic_shift(R, 1)

for R in Mb:
R.append(0)

return G,Mb
return G, Mb


def DM_52_6_1():
r"""
Expand Down
6 changes: 3 additions & 3 deletions src/sage/combinat/diagram_algebras.py
Original file line number Diff line number Diff line change
Expand Up @@ -4419,7 +4419,7 @@ def key_func(P):
else:
from sage.typeset.ascii_art import AsciiArt
d = [".", ".", "`", "`", "-", "|"]
#db = [".", ".", "`", "`", "=", "|"]
# db = [".", ".", "`", "`", "=", "|"]
blob = '0'
ret = [" o" * n]
char_art = AsciiArt
Expand Down Expand Up @@ -4489,12 +4489,12 @@ def sgn(x):
if x < 0:
return -1
return 0

l1 = [] # list of blocks
l2 = [] # list of nodes
for i in list(diagram):
l1.append(list(i))
for j in list(i):
l2.append(j)
l2.extend(list(i))
output = "\\begin{tikzpicture}[scale = 0.5,thick, baseline={(0,-1ex/2)}] \n\\tikzstyle{vertex} = [shape = circle, minimum size = 7pt, inner sep = 1pt] \n" #setup beginning of picture
for i in l2: #add nodes
output = output + "\\node[vertex] (G-{}) at ({}, {}) [shape = circle, draw{}] {{}}; \n".format(i, (abs(i)-1)*1.5, sgn(i), filled_str)
Expand Down
18 changes: 9 additions & 9 deletions src/sage/combinat/plane_partition.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,22 +314,22 @@ def x_tableau(self, tableau=True) -> Tableau:
return Tableau(X)
return X

def cells(self) -> list[list[int]]:
def cells(self) -> list[tuple[int, int, int]]:
r"""
Return the list of cells inside ``self``.
Each cell is a tuple.
EXAMPLES::
sage: PP = PlanePartition([[3,1],[2]])
sage: PP.cells()
[[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], [1, 0, 0], [1, 0, 1]]
"""
L = []
for r in range(len(self)):
for c in range(len(self[r])):
for h in range(self[r][c]):
L.append([r, c, h])
return L
[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 1, 0), (1, 0, 0), (1, 0, 1)]
"""
return [(r, c, h)
for r in range(len(self))
for c in range(len(self[r]))
for h in range(self[r][c])]

def number_of_boxes(self) -> Integer:
r"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,7 @@ def __init__(self, parent, rigged_partitions=[], **options):
if len(data) == 0:
# Create a size n array of empty rigged tableau since no tableau
# were given
nu = []
for i in range(n):
nu.append(RiggedPartition())
nu = [RiggedPartition() for _ in range(n)]
else:
if len(data) != n: # otherwise n should be equal to the number of tableaux
raise ValueError("incorrect number of partitions")
Expand Down Expand Up @@ -1308,9 +1306,8 @@ def __init__(self, parent, rigged_partitions=[], **options):
shape_data = data[0]
rigging_data = data[1]
vac_data = data[2]
nu = []
for i in range(n):
nu.append(RiggedPartition(shape_data[i], rigging_data[i], vac_data[i]))
nu = [RiggedPartition(a, b, c)
for a, b, c in zip(shape_data, rigging_data, vac_data)]
# Special display case
if parent.cartan_type().type() == 'B':
nu[-1] = RiggedPartitionTypeB(nu[-1])
Expand Down
3 changes: 1 addition & 2 deletions src/sage/combinat/set_partition.py
Original file line number Diff line number Diff line change
Expand Up @@ -1873,8 +1873,7 @@ def arcs(self):
arcs = []
for p in self:
p = sorted(p)
for i in range(len(p) - 1):
arcs.append((p[i], p[i + 1]))
arcs.extend((p[i], p[i + 1]) for i in range(len(p) - 1))
return arcs

def plot(self, angle=None, color='black', base_set_dict=None):
Expand Down
6 changes: 2 additions & 4 deletions src/sage/combinat/sf/new_kschur.py
Original file line number Diff line number Diff line change
Expand Up @@ -1595,10 +1595,8 @@ def _DualGrothMatrix(self, m):
for i in range(m + 1):
for x in Partitions(m - i, max_part=self.k):
f = mon(G(x, m))
vec = []
for j in range(m + 1):
for y in Partitions(m - j, max_part=self.k):
vec.append(f.coefficient(y))
vec = [f.coefficient(y) for j in range(m + 1)
for y in Partitions(m - j, max_part=self.k)]
new_mat.append(vec)
from sage.matrix.constructor import Matrix
return Matrix(new_mat)
Expand Down
17 changes: 7 additions & 10 deletions src/sage/combinat/sf/ns_macdonald.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def flip(self):

def boxes_same_and_lower_right(self, ii, jj):
"""
Return a list of the boxes of ``self`` that are in row ``jj``
Return an iterator of the boxes of ``self`` that are in row ``jj``
but not identical with ``(ii, jj)``, or lie in the row
``jj - 1`` (the row directly below ``jj``; this might be the
basement) and strictly to the right of ``(ii, jj)``.
Expand All @@ -168,26 +168,23 @@ def boxes_same_and_lower_right(self, ii, jj):
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]])
sage: a = a.shape()
sage: a.boxes_same_and_lower_right(1,1)
sage: list(a.boxes_same_and_lower_right(1,1))
[(2, 1), (3, 1), (6, 1), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0)]
sage: a.boxes_same_and_lower_right(1,2)
sage: list(a.boxes_same_and_lower_right(1,2))
[(3, 2), (6, 2), (2, 1), (3, 1), (6, 1)]
sage: a.boxes_same_and_lower_right(3,3)
sage: list(a.boxes_same_and_lower_right(3,3))
[(6, 2)]
sage: a.boxes_same_and_lower_right(2,3)
sage: list(a.boxes_same_and_lower_right(2,3))
[(3, 3), (3, 2), (6, 2)]
"""
res = []
# Add all of the boxes in the same row
for i in range(1, len(self) + 1):
if self[i] >= jj and i != ii:
res.append((i, jj))
yield (i, jj)

for i in range(ii + 1, len(self) + 1):
if self[i] >= jj - 1:
res.append((i, jj - 1))

return res
yield (i, jj - 1)


class AugmentedLatticeDiagramFilling(CombinatorialObject):
Expand Down
10 changes: 3 additions & 7 deletions src/sage/combinat/tableau.py
Original file line number Diff line number Diff line change
Expand Up @@ -2613,16 +2613,12 @@ def slide_multiply(self, other):
sage: t.slide_multiply(t2)
[[1, 1, 2, 2, 3], [2, 2, 3, 5], [3, 4, 5], [4, 6, 6], [5]]
"""
st = []
if len(self) == 0:
return other
else:
l = len(self[0])

for row in other:
st.append((None,)*l + row)
for row in self:
st.append(row)
l = len(self[0])
st = [(None,) * l + row for row in other]
st.extend(self)

from sage.combinat.skew_tableau import SkewTableau
return SkewTableau(st).rectify()
Expand Down
6 changes: 3 additions & 3 deletions src/sage/combinat/words/morphism.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ def _build_dict(self, s):

def _build_codomain(self, data):
r"""
Return a Words domain containing all the letter in the keys of
Return a Words domain containing all the letters in the values of
data (which must be a dictionary).
TESTS:
Expand All @@ -489,10 +489,10 @@ def _build_codomain(self, data):
Finite words over {0, 1, 2}
"""
codom_alphabet = set()
for key, val in data.items():
for val in data.values():
try:
it = iter(val)
except Exception:
except TypeError:
it = [val]
codom_alphabet.update(it)
try:
Expand Down

0 comments on commit a145be7

Please sign in to comment.