Iterables公司#
- class sympy.utilities.iterables.NotIterable[源代码]#
Use this as mixin when creating a class which is not supposed to return true when iterable() is called on its instances because calling list() on the instance, for example, would result in an infinite loop.
- sympy.utilities.iterables.binary_partitions(n)[源代码]#
Generates the binary partition of n.
一个二进制分区只包含2的幂次数。每一步减少 \(2^{{k+1}}\) 到 \(2^k\) 和 \(2^k\) . 因此16被转换成8和8。
实例
>>> from sympy.utilities.iterables import binary_partitions >>> for i in binary_partitions(5): ... print(i) ... [4, 1] [2, 2, 1] [2, 1, 1, 1] [1, 1, 1, 1, 1]
工具书类
[R1053]TAOCP 4,第7.2.1.5节,问题64
- sympy.utilities.iterables.capture(func)[源代码]#
返回func()的打印输出。
func
应该是一个不带参数的函数,该函数使用print语句生成输出。>>> from sympy.utilities.iterables import capture >>> from sympy import pprint >>> from sympy.abc import x >>> def foo(): ... print('hello world!') ... >>> 'hello' in capture(foo) # foo, not foo() True >>> capture(lambda: pprint(2/x)) '2\n-\nx\n'
- sympy.utilities.iterables.common_prefix(*seqs)[源代码]#
返回子序列,该子序列是
seqs
.>>> from sympy.utilities.iterables import common_prefix >>> common_prefix(list(range(3))) [0, 1, 2] >>> common_prefix(list(range(3)), list(range(4))) [0, 1, 2] >>> common_prefix([1, 2, 3], [1, 2, 5]) [1, 2] >>> common_prefix([1, 2, 3], [1, 3, 5]) [1]
- sympy.utilities.iterables.common_suffix(*seqs)[源代码]#
返回中序列的公共结尾的子序列
seqs
.>>> from sympy.utilities.iterables import common_suffix >>> common_suffix(list(range(3))) [0, 1, 2] >>> common_suffix(list(range(3)), list(range(4))) [] >>> common_suffix([1, 2, 3], [9, 2, 3]) [2, 3] >>> common_suffix([1, 2, 3], [9, 7, 3]) [3]
- sympy.utilities.iterables.connected_components(G)[源代码]#
无向图的连通分量或有向图的弱连通分量。
- 参数:
G : tuple[list, list[tuple[T, T]]
一种元组,由一组顶点和一组边组成,图的连通部分可以找到。
实例
给定一个无向图:
graph { A -- B C -- D }
如果我们在两个方向上包含每条边,则可以使用此函数找到连接的组件:
>>> from sympy.utilities.iterables import connected_components >>> V = ['A', 'B', 'C', 'D'] >>> E = [('A', 'B'), ('B', 'A'), ('C', 'D'), ('D', 'C')] >>> connected_components((V, E)) [['A', 'B'], ['C', 'D']]
有向图的弱连通分量也可以用同样的方法求出。
笔记
对于所使用的数据结构,图的顶点必须是散列的。如果顶点不易损坏,则将其替换为整数索引。
此函数使用Tarjan算法计算 \(O(|V|+|E|)\) (线性)时间。
工具书类
- sympy.utilities.iterables.filter_symbols(iterator, exclude)[源代码]#
只从 \(iterator\) 不会发生在 \(exclude\) .
- 参数:
迭代器 :i可读取
iterator to take elements from
排除 :i可读取
elements to exclude
- 返回:
迭代器 :迭代器
过滤迭代器
- sympy.utilities.iterables.flatten(iterable, levels=None, cls=None)[源代码]#
递归密度最大的iterable容器。
>>> from sympy import flatten
>>> flatten([1, 2, 3]) [1, 2, 3] >>> flatten([1, 2, [3]]) [1, 2, 3] >>> flatten([1, [2, 3], [4, 5]]) [1, 2, 3, 4, 5] >>> flatten([1.0, 2, (1, None)]) [1.0, 2, 1, None]
如果只想对嵌套容器的指定级别进行最密集,则设置
levels
标记到所需的级别数:>>> ls = [[(-2, -1), (1, 2)], [(0, 0)]]
>>> flatten(ls, levels=1) [(-2, -1), (1, 2), (0, 0)]
如果指定了cls参数,它将只展平该类的实例,例如:
>>> from sympy import Basic, S >>> class MyOp(Basic): ... pass ... >>> flatten([MyOp(S(1), MyOp(S(2), S(3)))], cls=MyOp) [1, 2, 3]
改编自https://kogs-www.informatik.uni hamburg.de/~meine/pythonu tricks
- sympy.utilities.iterables.generate_bell(n)[源代码]#
返回的排列 [0, 1, ..., n - 1] 这样每一个排列都通过交换一对邻居而与上一个排列不同。这个
n!
置换作为迭代器返回。为了从随机开始排列中获得下一个排列,请使用next_trotterjohnson
置换类的方法(以不同的方式生成相同的序列)。实例
>>> from itertools import permutations >>> from sympy.utilities.iterables import generate_bell >>> from sympy import zeros, Matrix
这是物理钟敲响时使用的一种排列方式,不产生字典顺序的排列。相反,置换彼此之间只存在一个反转,并且交换发生的位置以简单的方式周期性地变化。考虑由
permutations
和generate_bell
:>>> list(permutations(range(4)))[:5] [(0, 1, 2, 3), (0, 1, 3, 2), (0, 2, 1, 3), (0, 2, 3, 1), (0, 3, 1, 2)] >>> list(generate_bell(4))[:5] [(0, 1, 2, 3), (0, 1, 3, 2), (0, 3, 1, 2), (3, 0, 1, 2), (3, 0, 2, 1)]
注意第二个和第三个字典排列是如何有3个元素错位的,而每个“bell”排列总是只有两个元素相对于前一个排列错位(因此,一个置换的签名(+/-1)与前一个排列的签名相反)。
通过追踪排列中出现最大数的位置,可以看出元素间反转的位置是如何变化的:
>>> m = zeros(4, 24) >>> for i, p in enumerate(generate_bell(4)): ... m[:, i] = Matrix([j - 3 for j in list(p)]) # make largest zero >>> m.print_nonzero('X') [XXX XXXXXX XXXXXX XXX] [XX XX XXXX XX XXXX XX XX] [X XXXX XX XXXX XX XXXX X] [ XXXXXX XXXXXX XXXXXX ]
工具书类
- sympy.utilities.iterables.generate_derangements(s)[源代码]#
Return unique derangements of the elements of iterable
s
.实例
>>> from sympy.utilities.iterables import generate_derangements >>> list(generate_derangements([0, 1, 2])) [[1, 2, 0], [2, 0, 1]] >>> list(generate_derangements([0, 1, 2, 2])) [[2, 2, 0, 1], [2, 2, 1, 0]] >>> list(generate_derangements([0, 1, 1])) []
- sympy.utilities.iterables.generate_involutions(n)[源代码]#
产生对合。
对合是一种置换,当与它自身相乘时等于单位置换。在这个实现中,对合是使用不动点生成的。
或者,对合可以被认为是不包含长度大于2的任何圈的置换。
实例
>>> from sympy.utilities.iterables import generate_involutions >>> list(generate_involutions(3)) [(0, 1, 2), (0, 2, 1), (1, 0, 2), (2, 1, 0)] >>> len(list(generate_involutions(4))) 10
工具书类
- sympy.utilities.iterables.generate_oriented_forest(n)[源代码]#
该算法生成有向森林。
有向图是没有对称有向边对的有向图。森林是一个无环图,即它没有循环。森林也可以被描述为一个不相交的树的并,树是一个图,其中任意两个顶点通过一条简单的路径连接起来。
实例
>>> from sympy.utilities.iterables import generate_oriented_forest >>> list(generate_oriented_forest(4)) [[0, 1, 2, 3], [0, 1, 2, 2], [0, 1, 2, 1], [0, 1, 2, 0], [0, 1, 1, 1], [0, 1, 1, 0], [0, 1, 0, 1], [0, 1, 0, 0], [0, 0, 0, 0]]
工具书类
[R1062]T、 Beyer和S.M.Hedetneimi:有根树的恒定时间生成,暹罗计算杂志,第9卷,第4期,1980年11月
- sympy.utilities.iterables.group(seq, multiple=True)[源代码]#
将序列拆分为相等相邻元素的列表。
实例
>>> from sympy import group
>>> group([1, 1, 1, 2, 2, 3]) [[1, 1, 1], [2, 2], [3]] >>> group([1, 1, 1, 2, 2, 3], multiple=False) [(1, 3), (2, 2), (3, 1)] >>> group([1, 1, 3, 2, 2, 1], multiple=False) [(1, 2), (3, 1), (2, 2), (1, 1)]
参见
- sympy.utilities.iterables.has_dups(seq)[源代码]#
如果中存在任何重复元素,则返回True
seq
.实例
>>> from sympy import has_dups, Dict, Set >>> has_dups((1, 2, 1)) True >>> has_dups(range(3)) False >>> all(has_dups(c) is False for c in (set(), Set(), dict(), Dict())) True
- sympy.utilities.iterables.has_variety(seq)[源代码]#
如果中有任何不同的元素,则返回True
seq
.实例
>>> from sympy import has_variety
>>> has_variety((1, 2, 1)) True >>> has_variety((1, 1, 1)) False
- sympy.utilities.iterables.ibin(n, bits=None, str=False)[源代码]#
返回长度列表
bits
对应于n
在右边有一小段(最后)。如果省略位,则长度将是表示所需的数字n
. 如果所需位的顺序相反,则使用[::-1]
返回列表的切片。如果所有位长度列表的序列从
[0, 0,..., 0]
通过[1, 1, ..., 1]
如果需要,则为位传递一个非整数,例如。'all'
.如果钻头 一串 是期望通过
str=True
.实例
>>> from sympy.utilities.iterables import ibin >>> ibin(2) [1, 0] >>> ibin(2, 4) [0, 0, 1, 0]
如果所有列表对应0到2**n-1,则为位传递一个非整数:
>>> bits = 2 >>> for i in ibin(2, 'all'): ... print(i) (0, 0) (0, 1) (1, 0) (1, 1)
如果需要给定长度的位字符串,请使用str=True:
>>> n = 123 >>> bits = 10 >>> ibin(n, bits, str=True) '0001111011' >>> ibin(n, bits, str=True)[::-1] # small bits left '1101111000' >>> list(ibin(3, 'all', str=True)) ['000', '001', '010', '011', '100', '101', '110', '111']
- sympy.utilities.iterables.iproduct(*iterables)[源代码]#
iterables的笛卡尔积。
Generator of the Cartesian product of iterables. This is analogous to itertools.product except that it works with infinite iterables and will yield any item from the infinite product eventually.
实例
>>> from sympy.utilities.iterables import iproduct >>> sorted(iproduct([1,2], [3,4])) [(1, 3), (1, 4), (2, 3), (2, 4)]
使用无限迭代器:
>>> from sympy import S >>> (3,) in iproduct(S.Integers) True >>> (3, 4) in iproduct(S.Integers, S.Integers) True
- sympy.utilities.iterables.is_palindromic(s, i=0, j=None)[源代码]#
Return True if the sequence is the same from left to right as it is from right to left in the whole sequence (default) or in the Python slice
s[i: j]
; else False.实例
>>> from sympy.utilities.iterables import is_palindromic >>> is_palindromic([1, 0, 1]) True >>> is_palindromic('abcbb') False >>> is_palindromic('abcbb', 1) False
正常的Python切片是就地执行的,因此不需要创建序列的切片来进行测试:
>>> is_palindromic('abcbb', 1, -1) True >>> is_palindromic('abcbb', -4, -1) True
- sympy.utilities.iterables.is_sequence(i, include=None)[源代码]#
返回一个布尔值,指示
i
是一个共感意义上的序列。如果任何未通过下面测试的内容应作为应用程序的序列包含,请将“include”设置为该对象的类型;应将多个类型作为类型的元组传递。注意:虽然生成器可以生成序列,但它们通常需要特殊处理,以确保在生成器耗尽之前捕获到它们的元素,因此默认情况下,序列的定义中不包括这些元素。
另见:iterable
实例
>>> from sympy.utilities.iterables import is_sequence >>> from types import GeneratorType >>> is_sequence([]) True >>> is_sequence(set()) False >>> is_sequence('abc') False >>> is_sequence('abc', include=str) True >>> generator = (c for c in 'abc') >>> is_sequence(generator) False >>> is_sequence(generator, include=(str, GeneratorType)) True
- sympy.utilities.iterables.iterable(i, exclude=(<class 'str'>, <class 'dict'>, <class 'sympy.utilities.iterables.NotIterable'>))[源代码]#
返回一个布尔值,指示
i
是可悲的。True还表示迭代器是有限的,例如,可以对实例调用list(…)。当SymPy使用iterables时,它几乎总是假定iterable不是字符串或映射,因此默认情况下排除了它们。如果需要纯Python定义,请使exclude=None。要排除多个项,请将它们作为元组传递。
您还可以将类的iterable属性设置为True或False,这将覆盖此处的检查,包括排除测试。
作为经验法则,一些SymPy函数使用它来检查它们是否应该递归地映射到一个对象上。如果一个对象在Python意义上技术上是可编辑的,但不希望有这种行为(例如,因为它的迭代不是有限的,或者因为迭代可能导致不需要的计算),那么它应该通过将itable属性设置为False来禁用它。
另请参阅:is_序列
实例
>>> from sympy.utilities.iterables import iterable >>> from sympy import Tuple >>> things = [[1], (1,), set([1]), Tuple(1), (j for j in [1, 2]), {1:2}, '1', 1] >>> for i in things: ... print('%s %s' % (iterable(i), type(i))) True <... 'list'> True <... 'tuple'> True <... 'set'> True <class 'sympy.core.containers.Tuple'> True <... 'generator'> False <... 'dict'> False <... 'str'> False <... 'int'>
>>> iterable({}, exclude=None) True >>> iterable({}, exclude=str) True >>> iterable("no", exclude=str) False
- sympy.utilities.iterables.kbins(l, k, ordered=None)[源代码]#
返回序列
l
分成k
箱子。实例
默认情况下,按相同的顺序排列项目,但将它们分组为k个分区,而不进行任何重新排序:
>>> from sympy.utilities.iterables import kbins >>> for p in kbins(list(range(5)), 2): ... print(p) ... [[0], [1, 2, 3, 4]] [[0, 1], [2, 3, 4]] [[0, 1, 2], [3, 4]] [[0, 1, 2, 3], [4]]
这个
ordered
flag要么是None(表示元素的简单分区),要么是一个2位数的整数,指示存储箱的顺序和存储箱中项目的顺序是否重要。鉴于::A = [[0], [1, 2]] B = [[1, 2], [0]] C = [[2, 1], [0]] D = [[0], [2, 1]]
以下值
ordered
意思如下:00 means A == B == C == D 01 means A == B 10 means A == D 11 means A == A
>>> for ordered_flag in [None, 0, 1, 10, 11]: ... print('ordered = %s' % ordered_flag) ... for p in kbins(list(range(3)), 2, ordered=ordered_flag): ... print(' %s' % p) ... ordered = None [[0], [1, 2]] [[0, 1], [2]] ordered = 0 [[0, 1], [2]] [[0, 2], [1]] [[0], [1, 2]] ordered = 1 [[0], [1, 2]] [[0], [2, 1]] [[1], [0, 2]] [[1], [2, 0]] [[2], [0, 1]] [[2], [1, 0]] ordered = 10 [[0, 1], [2]] [[2], [0, 1]] [[0, 2], [1]] [[1], [0, 2]] [[0], [1, 2]] [[1, 2], [0]] ordered = 11 [[0], [1, 2]] [[0, 1], [2]] [[0], [2, 1]] [[0, 2], [1]] [[1], [0, 2]] [[1, 0], [2]] [[1], [2, 0]] [[1, 2], [0]] [[2], [0, 1]] [[2, 0], [1]] [[2], [1, 0]] [[2, 1], [0]]
- sympy.utilities.iterables.least_rotation(x, key=None)[源代码]#
返回获得字典式最小字符串/列表/元组等所需的左旋转步数。
实例
>>> from sympy.utilities.iterables import least_rotation, rotate_left >>> a = [3, 1, 5, 1, 2] >>> least_rotation(a) 3 >>> rotate_left(a, _) [1, 2, 3, 1, 5]
工具书类
- sympy.utilities.iterables.minlex(seq, directed=True, key=None)[源代码]#
Return the rotation of the sequence in which the lexically smallest elements appear first, e.g. \(cba \rightarrow acb\).
The sequence returned is a tuple, unless the input sequence is a string in which case a string is returned.
If
directed
is False then the smaller of the sequence and the reversed sequence is returned, e.g. \(cba \rightarrow abc\).If
key
is not None then it is used to extract a comparison key from each element in iterable.实例
>>> from sympy.combinatorics.polyhedron import minlex >>> minlex((1, 2, 0)) (0, 1, 2) >>> minlex((1, 0, 2)) (0, 2, 1) >>> minlex((1, 0, 2), directed=False) (0, 1, 2)
>>> minlex('11010011000', directed=True) '00011010011' >>> minlex('11010011000', directed=False) '00011001011'
>>> minlex(('bb', 'aaa', 'c', 'a')) ('a', 'bb', 'aaa', 'c') >>> minlex(('bb', 'aaa', 'c', 'a'), key=len) ('c', 'a', 'bb', 'aaa')
- sympy.utilities.iterables.multiset(seq)[源代码]#
以multiset形式返回散列序列,值为序列中项的重数。
实例
>>> from sympy.utilities.iterables import multiset >>> multiset('mississippi') {'i': 4, 'm': 1, 'p': 2, 's': 4}
参见
- sympy.utilities.iterables.multiset_combinations(m, n, g=None)[源代码]#
返回大小的唯一组合
n
从multisetm
.实例
>>> from sympy.utilities.iterables import multiset_combinations >>> from itertools import combinations >>> [''.join(i) for i in multiset_combinations('baby', 3)] ['abb', 'aby', 'bby']
>>> def count(f, s): return len(list(f(s, 3)))
组合的数量取决于字母的数量;唯一组合的数量取决于字母的重复方式。
>>> s1 = 'abracadabra' >>> s2 = 'banana tree' >>> count(combinations, s1), count(multiset_combinations, s1) (165, 23) >>> count(combinations, s2), count(multiset_combinations, s2) (165, 54)
- sympy.utilities.iterables.multiset_derangements(s)[源代码]#
Generate derangements of the elements of s in place.
实例
>>> from sympy.utilities.iterables import multiset_derangements, uniq
Because the derangements of multisets (not sets) are generated in place, copies of the return value must be made if a collection of derangements is desired or else all values will be the same:
>>> list(uniq([i for i in multiset_derangements('1233')])) [[None, None, None, None]] >>> [i.copy() for i in multiset_derangements('1233')] [['3', '3', '1', '2'], ['3', '3', '2', '1']] >>> [''.join(i) for i in multiset_derangements('1233')] ['3312', '3321']
- sympy.utilities.iterables.multiset_partitions(multiset, m=None)[源代码]#
返回给定multiset的唯一分区(以列表形式)。如果
m
为None时,将返回所有multisets,否则只返回m
零件将被退回。如果
multiset
是整数,范围 [0, 1, ..., multiset - 1] 将提供。实例
>>> from sympy.utilities.iterables import multiset_partitions >>> list(multiset_partitions([1, 2, 3, 4], 2)) [[[1, 2, 3], [4]], [[1, 2, 4], [3]], [[1, 2], [3, 4]], [[1, 3, 4], [2]], [[1, 3], [2, 4]], [[1, 4], [2, 3]], [[1], [2, 3, 4]]] >>> list(multiset_partitions([1, 2, 3, 4], 1)) [[[1, 2, 3, 4]]]
只返回唯一的分区,这些分区将按规范顺序返回,而不考虑输入的顺序:
>>> a = [1, 2, 2, 1] >>> ans = list(multiset_partitions(a, 2)) >>> a.sort() >>> list(multiset_partitions(a, 2)) == ans True >>> a = range(3, 1, -1) >>> (list(multiset_partitions(a)) == ... list(multiset_partitions(sorted(a)))) True
如果省略m,则将返回所有分区:
>>> list(multiset_partitions([1, 1, 2])) [[[1, 1, 2]], [[1, 1], [2]], [[1, 2], [1]], [[1], [1], [2]]] >>> list(multiset_partitions([1]*3)) [[[1, 1, 1]], [[1], [1, 1]], [[1], [1], [1]]]
计数
一组的分区数由贝尔数给出:
>>> from sympy import bell >>> len(list(multiset_partitions(5))) == bell(5) == 52 True
从一个大小n的集合中,长度为k的分区数由第2类的Stirling数给出:
>>> from sympy.functions.combinatorial.numbers import stirling >>> stirling(5, 2) == len(list(multiset_partitions(5, 2))) == 15 True
这些关于计数的意见适用于 sets ,不是多集。
笔记
当multiset中的所有元素都相同时,返回分区的顺序由
partitions
例行公事。如果要计算分区,则最好使用nT
功能。
- sympy.utilities.iterables.multiset_permutations(m, size=None, g=None)[源代码]#
返回multiset的唯一置换
m
.实例
>>> from sympy.utilities.iterables import multiset_permutations >>> from sympy import factorial >>> [''.join(i) for i in multiset_permutations('aab')] ['aab', 'aba', 'baa'] >>> factorial(len('banana')) 720 >>> len(list(multiset_permutations('banana'))) 60
- sympy.utilities.iterables.necklaces(n, k, free=False)[源代码]#
生成项链的例程,这些项链可能(free=True)或not(free=False)被翻转查看。返回的“项链”包括
n
整数(珠子)k
不同的值(颜色)。只退回独特的项链。实例
>>> from sympy.utilities.iterables import necklaces, bracelets >>> def show(s, i): ... return ''.join(s[j] for j in i)
“不受限制的项链”有时也被称为“手镯”(一个可以翻转的物体,一个可以颠倒的序列),“项链”一词用来暗示一个不能颠倒的序列。所以ACB==ABC对于手镯(旋转和反转),而对于项链来说两者是不同的,因为仅仅旋转不能使两个序列相同。
(助记符:手镯可以向后看,但项链不能看。)
>>> B = [show('ABC', i) for i in bracelets(3, 3)] >>> N = [show('ABC', i) for i in necklaces(3, 3)] >>> set(N) - set(B) {'ACB'}
>>> list(necklaces(4, 2)) [(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 1, 1), (0, 1, 0, 1), (0, 1, 1, 1), (1, 1, 1, 1)]
>>> [show('.o', i) for i in bracelets(4, 2)] ['....', '...o', '..oo', '.o.o', '.ooo', 'oooo']
工具书类
[R1066]Frank Ruskey, Carla Savage, and Terry Min Yih Wang, Generating necklaces, Journal of Algorithms 13 (1992), 414-430; https://doi.org/10.1016/0196-6774(92)90047-G
- sympy.utilities.iterables.numbered_symbols(prefix='x', cls=None, start=0, exclude=(), *args, **assumptions)[源代码]#
生成由前缀和递增下标组成的无限符号流,前提是它们不出现在
exclude
.- 参数:
前缀 :str,可选
要使用的前缀。默认情况下,此函数将生成“x0”、“x1”等形式的符号。
cls :类,可选
要使用的类。默认情况下,它使用
Symbol
,但也可以使用Wild
或Dummy
.开始 :int,可选
起始号码。默认为0。
exclude : list, tuple, set of cls, optional
Symbols to be excluded.
*args, **kwargs
Additional positional and keyword arguments are passed to the cls class.
- 返回:
sym :符号
下标符号。
- sympy.utilities.iterables.ordered_partitions(n, m=None, sort=True)[源代码]#
Generates ordered partitions of integer n.
- 参数:
n :内景
m : int, optional
The default value gives partitions of all sizes else only those with size m. In addition, if m is not None then partitions are generated in place (see examples).
sort : bool, default: True
Controls whether partitions are returned in sorted order when m is not None; when False, the partitions are returned as fast as possible with elements sorted, but when m|n the partitions will not be in ascending lexicographical order.
实例
>>> from sympy.utilities.iterables import ordered_partitions
升序词典中5的所有分区:
>>> for p in ordered_partitions(5): ... print(p) [1, 1, 1, 1, 1] [1, 1, 1, 2] [1, 1, 3] [1, 2, 2] [1, 4] [2, 3] [5]
只有5个分区,包括两个部分:
>>> for p in ordered_partitions(5, 2): ... print(p) [1, 4] [2, 3]
什么时候?
m
如果给定,则由于速度原因,将多次使用给定的列表对象,因此除非在生成每个对象时对每个对象进行副本,否则将看不到正确的分区:>>> [p for p in ordered_partitions(7, 3)] [[1, 1, 1], [1, 1, 1], [1, 1, 1], [2, 2, 2]] >>> [list(p) for p in ordered_partitions(7, 3)] [[1, 1, 5], [1, 2, 4], [1, 3, 3], [2, 2, 3]]
什么时候?
n
是的倍数m
,元素仍然被排序,但分区本身将被排序 无序 如果sort为False,则默认值是按字典顺序升序返回它们。>>> for p in ordered_partitions(6, 2): ... print(p) [1, 5] [2, 4] [3, 3]
但是,如果速度比排序更重要,则可以将sort设置为False:
>>> for p in ordered_partitions(6, 2, sort=False): ... print(p) [1, 5] [3, 3] [2, 4]
工具书类
[R1067]生成整数分区, [在线] ,可用:https://jeromekelleher.net/generating-integer-partitions.html
[R1068]Jerome Kelleher和Barry O'Sullivan,“生成所有分区:两种编码的比较”, [在线] ,可用:https://arxiv.org/pdf/0909.2331v2.pdf
- sympy.utilities.iterables.partitions(n, m=None, k=None, size=False)[源代码]#
生成正整数n的所有分区。
Each partition is represented as a dictionary, mapping an integer to the number of copies of that integer in the partition. For example, the first partition of 4 returned is {4: 1}, "4: one of them".
- 参数:
n :内景
m : int, optional
限制分区中的部分数(助记符:m,最大部分)
k :int,可选
限制保存在分区中的数字(助记符:k,keys)
size : bool, default: False
If
True
, (M, P) is returned where M is the sum of the multiplicities and P is the generated partition. IfFalse
, only the generated partition is returned.
实例
>>> from sympy.utilities.iterables import partitions
分区中出现的数字(返回dict的键)受k限制:
>>> for p in partitions(6, k=2): ... print(p) {2: 3} {1: 2, 2: 2} {1: 4, 2: 1} {1: 6}
分区中的最大部分数(返回dict中的值之和)受m限制(默认值为None,给出从1到n的分区):
>>> for p in partitions(6, m=2): ... print(p) ... {6: 1} {1: 1, 5: 1} {2: 1, 4: 1} {3: 2}
工具书类
[R1069]modified from Tim Peter's version to allow for k and m values: https://code.activestate.com/recipes/218332-generator-for-integer-partitions/
- sympy.utilities.iterables.permute_signs(t)[源代码]#
返回迭代器,其中t的非零元素的符号被置换。
实例
>>> from sympy.utilities.iterables import permute_signs >>> list(permute_signs((0, 1, 2))) [(0, 1, 2), (0, -1, 2), (0, 1, -2), (0, -1, -2)]
- sympy.utilities.iterables.postfixes(seq)[源代码]#
生成序列的所有后缀。
实例
>>> from sympy.utilities.iterables import postfixes
>>> list(postfixes([1,2,3,4])) [[4], [3, 4], [2, 3, 4], [1, 2, 3, 4]]
- sympy.utilities.iterables.prefixes(seq)[源代码]#
生成序列的所有前缀。
实例
>>> from sympy.utilities.iterables import prefixes
>>> list(prefixes([1,2,3,4])) [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4]]
- sympy.utilities.iterables.random_derangement(t, choice=None, strict=True)[源代码]#
Return a list of elements in which none are in the same positions as they were originally. If an element fills more than half of the positions then an error will be raised since no derangement is possible. To obtain a derangement of as many items as possible--with some of the most numerous remaining in their original positions--pass \(strict=False\). To produce a pseudorandom derangment, pass a pseudorandom selector like \(choice\) (see below).
实例
>>> from sympy.utilities.iterables import random_derangement >>> t = 'SymPy: a CAS in pure Python' >>> d = random_derangement(t) >>> all(i != j for i, j in zip(d, t)) True
A predictable result can be obtained by using a pseudorandom generator for the choice:
>>> from sympy.core.random import seed, choice as c >>> seed(1) >>> d = [''.join(random_derangement(t, c)) for i in range(5)] >>> assert len(set(d)) != 1 # we got different values
By reseeding, the same sequence can be obtained:
>>> seed(1) >>> d2 = [''.join(random_derangement(t, c)) for i in range(5)] >>> assert d == d2
- sympy.utilities.iterables.reshape(seq, how)[源代码]#
根据中的模板重塑序列
how
.实例
>>> from sympy.utilities import reshape >>> seq = list(range(1, 9))
>>> reshape(seq, [4]) # lists of 4 [[1, 2, 3, 4], [5, 6, 7, 8]]
>>> reshape(seq, (4,)) # tuples of 4 [(1, 2, 3, 4), (5, 6, 7, 8)]
>>> reshape(seq, (2, 2)) # tuples of 4 [(1, 2, 3, 4), (5, 6, 7, 8)]
>>> reshape(seq, (2, [2])) # (i, i, [i, i]) [(1, 2, [3, 4]), (5, 6, [7, 8])]
>>> reshape(seq, ((2,), [2])) # etc.... [((1, 2), [3, 4]), ((5, 6), [7, 8])]
>>> reshape(seq, (1, [2], 1)) [(1, [2, 3], 4), (5, [6, 7], 8)]
>>> reshape(tuple(seq), ([[1], 1, (2,)],)) (([[1], 2, (3, 4)],), ([[5], 6, (7, 8)],))
>>> reshape(tuple(seq), ([1], 1, (2,))) (([1], 2, (3, 4)), ([5], 6, (7, 8)))
>>> reshape(list(range(12)), [2, [3], {2}, (1, (3,), 1)]) [[0, 1, [2, 3, 4], {5, 6}, (7, (8, 9, 10), 11)]]
- sympy.utilities.iterables.rotate_left(x, y)[源代码]#
按y中指定的步数向左旋转列表x。
实例
>>> from sympy.utilities.iterables import rotate_left >>> a = [0, 1, 2] >>> rotate_left(a, 1) [1, 2, 0]
- sympy.utilities.iterables.rotate_right(x, y)[源代码]#
按y中指定的步数向右旋转列表x。
实例
>>> from sympy.utilities.iterables import rotate_right >>> a = [0, 1, 2] >>> rotate_right(a, 1) [2, 0, 1]
- sympy.utilities.iterables.rotations(s, dir=1)[源代码]#
Return a generator giving the items in s as list where each subsequent list has the items rotated to the left (default) or right (
dir=-1
) relative to the previous list.实例
>>> from sympy import rotations >>> list(rotations([1,2,3])) [[1, 2, 3], [2, 3, 1], [3, 1, 2]] >>> list(rotations([1,2,3], -1)) [[1, 2, 3], [3, 1, 2], [2, 3, 1]]
- sympy.utilities.iterables.roundrobin(*iterables)[源代码]#
roundrobin recipe taken from itertools documentation: https://docs.python.org/3/library/itertools.html#itertools-recipes
roundrobin('ABC','D','EF')-->A D E B F C
这是乔治·萨基斯的食谱
- sympy.utilities.iterables.runs(seq, op=<built-in function gt>)[源代码]#
将序列分组为列表,其中连续元素都与比较运算符进行比较,
op
:操作(顺序 [我+1] SEQ [i] )对于运行中的所有元素都为True。实例
>>> from sympy.utilities.iterables import runs >>> from operator import ge >>> runs([0, 1, 2, 2, 1, 4, 3, 2, 2]) [[0, 1, 2], [2], [1, 4], [3], [2], [2]] >>> runs([0, 1, 2, 2, 1, 4, 3, 2, 2], op=ge) [[0, 1, 2, 2], [1, 4], [3], [2, 2]]
- sympy.utilities.iterables.sequence_partitions(l, n, /)[源代码]#
Returns the partition of sequence \(l\) into \(n\) bins
- 参数:
l : Sequence[T]
A nonempty sequence of any Python objects
n :内景
A positive integer
- 产量:
out : list[Sequence[T]]
A list of sequences with concatenation equals \(l\). This should conform with the type of \(l\).
解释
Given the sequence \(l_1 \cdots l_m \in V^+\) where \(V^+\) is the Kleene plus of \(V\)
The set of \(n\) partitions of \(l\) is defined as:
\[\{(s_1, \cdots, s_n) | s_1 \in V^+, \cdots, s_n \in V^+, s_1 \cdots s_n = l_1 \cdots l_m\}\]实例
>>> from sympy.utilities.iterables import sequence_partitions >>> for out in sequence_partitions([1, 2, 3, 4], 2): ... print(out) [[1], [2, 3, 4]] [[1, 2], [3, 4]] [[1, 2, 3], [4]]
笔记
This is modified version of EnricoGiampieri's partition generator from https://stackoverflow.com/questions/13131491/partition-n-items-into-k-bins-in-python-lazily
- sympy.utilities.iterables.sequence_partitions_empty(l, n, /)[源代码]#
Returns the partition of sequence \(l\) into \(n\) bins with empty sequence
- 参数:
l : Sequence[T]
A sequence of any Python objects (can be possibly empty)
n :内景
A positive integer
- 产量:
out : list[Sequence[T]]
A list of sequences with concatenation equals \(l\). This should conform with the type of \(l\).
解释
Given the sequence \(l_1 \cdots l_m \in V^*\) where \(V^*\) is the Kleene star of \(V\)
The set of \(n\) partitions of \(l\) is defined as:
\[\{(s_1, \cdots, s_n) | s_1 \in V^*, \cdots, s_n \in V^*, s_1 \cdots s_n = l_1 \cdots l_m\}\]There are more combinations than
sequence_partitions()
because empty sequence can fill everywhere, so we try to provide different utility for this.实例
>>> from sympy.utilities.iterables import sequence_partitions_empty >>> for out in sequence_partitions_empty([1, 2, 3, 4], 2): ... print(out) [[], [1, 2, 3, 4]] [[1], [2, 3, 4]] [[1, 2], [3, 4]] [[1, 2, 3], [4]] [[1, 2, 3, 4], []]
- sympy.utilities.iterables.sift(seq, keyfunc, binary=False)[源代码]#
筛选序列,
seq
根据keyfunc
.- 返回:
什么时候?
binary
是False
(默认),输出是字典where元素
seq
存储在键控到值的列表中该元素的keyfunc。如果
binary
是真的那么一个元组带列表
T
和F
返回到哪里T
是一个列表包含seq元素的
keyfunc
是True
和F
包含那些元素keyfunc
是False
;如果
keyfunc
不是二进制的。
实例
>>> from sympy.utilities import sift >>> from sympy.abc import x, y >>> from sympy import sqrt, exp, pi, Tuple
>>> sift(range(5), lambda x: x % 2) {0: [0, 2, 4], 1: [1, 3]}
sift()返回一个defaultdict()对象,因此任何没有匹配项的键都将给出[]。
>>> sift([x], lambda x: x.is_commutative) {True: [x]} >>> _[False] []
有时你不知道你会得到多少钥匙:
>>> sift([sqrt(x), exp(x), (y**x)**2], ... lambda x: x.as_base_exp()[0]) {E: [exp(x)], x: [sqrt(x)], y: [y**(2*x)]}
有时您希望结果是二进制的;可以通过设置
binary
为真:>>> sift(range(4), lambda x: x % 2, binary=True) ([1, 3], [0, 2]) >>> sift(Tuple(1, pi), lambda x: x.is_rational, binary=True) ([1], [pi])
如果谓词实际上不是二进制的,则会引发ValueError(这对于使用筛选和期望二进制结果的逻辑来说是一个很好的测试):
>>> unknown = exp(1) - pi # the rationality of this is unknown >>> args = Tuple(1, pi, unknown) >>> sift(args, lambda x: x.is_rational, binary=True) Traceback (most recent call last): ... ValueError: keyfunc gave non-binary output
非二进制筛选显示生成了3个密钥:
>>> set(sift(args, lambda x: x.is_rational).keys()) {None, False, True}
如果你需要对筛选出来的项目进行排序,最好使用
ordered
它可以在排序时经济地将多个排序键应用于一个序列。参见
- sympy.utilities.iterables.signed_permutations(t)[源代码]#
Return iterator in which the signs of non-zero elements of t and the order of the elements are permuted and all returned values are unique.
实例
>>> from sympy.utilities.iterables import signed_permutations >>> list(signed_permutations((0, 1, 2))) [(0, 1, 2), (0, -1, 2), (0, 1, -2), (0, -1, -2), (0, 2, 1), (0, -2, 1), (0, 2, -1), (0, -2, -1), (1, 0, 2), (-1, 0, 2), (1, 0, -2), (-1, 0, -2), (1, 2, 0), (-1, 2, 0), (1, -2, 0), (-1, -2, 0), (2, 0, 1), (-2, 0, 1), (2, 0, -1), (-2, 0, -1), (2, 1, 0), (-2, 1, 0), (2, -1, 0), (-2, -1, 0)]
- sympy.utilities.iterables.strongly_connected_components(G)[源代码]#
逆拓扑序有向图的强连通分量。
- 参数:
G : tuple[list, list[tuple[T, T]]
图的一种元组,由一组顶点和一组边组成,图的强连通分量是要找到的。
实例
考虑有向图(用点表示法)::
digraph { A -> B A -> C B -> C C -> B B -> D }
其中顶点是字母A、B、C和D。此图可以使用Python的基本数据结构进行编码,如下所示:
>>> V = ['A', 'B', 'C', 'D'] >>> E = [('A', 'B'), ('A', 'C'), ('B', 'C'), ('C', 'B'), ('B', 'D')]
图的强连通分量可以计算为
>>> from sympy.utilities.iterables import strongly_connected_components
>>> strongly_connected_components((V, E)) [['D'], ['B', 'C'], ['A']]
这也给出了组件的反向拓扑顺序。
因为包含B和C的子图有一个圈,它们必须在一个强连通的分量中。A和D连接到图的其余部分,但不是以循环方式连接的,因此它们显示为自己的强连接组件。
笔记
对于所使用的数据结构,图的顶点必须是散列的。如果顶点不易损坏,则将其替换为整数索引。
此函数使用Tarjan算法计算 \(O(|V|+|E|)\) (线性)时间。
工具书类
- sympy.utilities.iterables.subsets(seq, k=None, repetition=False)[源代码]#
生成所有 \(k\) -来自 \(n\) -元素集,
seq
.A \(k\) -一个 \(n\) -元素集正好是长度的任何子集 \(k\) . 数量 \(k\) -的子集 \(n\) -元素集由
binomial(n, k)
,而有 \(2^n\) 集合在一起。如果 \(k\) 是None
然后全部 \(2^n\) 子集将从最短返回到最长。实例
>>> from sympy import subsets
subsets(seq, k)
将返回 \(\frac{{n!}}{{k!(n - k)!}}\) \(k\) -没有重复的子集(组合),即一旦一个项目被移除,就不能再“获取”:>>> list(subsets([1, 2], 2)) [(1, 2)] >>> list(subsets([1, 2])) [(), (1,), (2,), (1, 2)] >>> list(subsets([1, 2, 3], 2)) [(1, 2), (1, 3), (2, 3)]
subsets(seq, k, repetition=True)
将返回 \(\frac{{(n - 1 + k)!}}{{k!(n - 1)!}}\) 组合 with 重复:>>> list(subsets([1, 2], 2, repetition=True)) [(1, 1), (1, 2), (2, 2)]
如果您要求的项目多于集合中的项目,则除非您允许重复,否则将得到空集合:
>>> list(subsets([0, 1], 3, repetition=False)) [] >>> list(subsets([0, 1], 3, repetition=True)) [(0, 0, 0), (0, 0, 1), (0, 1, 1), (1, 1, 1)]
- sympy.utilities.iterables.topological_sort(graph, key=None)[源代码]#
图的顶点的拓扑排序。
- 参数:
图表 :元组 [列表,列表[元组[T,T] ]
一种元组,由一组顶点和一组要拓扑排序的图的边组成。
key :可调用 [T] (可选)
同一级别上顶点的排序键。默认情况下,使用自然(例如字典)排序(在这种情况下,基类型必须实现排序关系)。
实例
考虑一个图表:
+---+ +---+ +---+ | 7 |\ | 5 | | 3 | +---+ \ +---+ +---+ | _\___/ ____ _/ | | / \___/ \ / | V V V V | +----+ +---+ | | 11 | | 8 | | +----+ +---+ | | | \____ ___/ _ | | \ \ / / \ | V \ V V / V V +---+ \ +---+ | +----+ | 2 | | | 9 | | | 10 | +---+ | +---+ | +----+ \________/
其中顶点是整数。此图可以使用基本Python的数据结构进行编码,如下所示:
>>> V = [2, 3, 5, 7, 8, 9, 10, 11] >>> E = [(7, 11), (7, 8), (5, 11), (3, 8), (3, 10), ... (11, 2), (11, 9), (11, 10), (8, 9)]
图的拓扑排序计算
(V, E)
发行日期:>>> from sympy.utilities.iterables import topological_sort >>> topological_sort((V, E)) [3, 5, 7, 8, 11, 2, 9, 10]
如果需要特定的断接方法,则使用
key
参数::>>> topological_sort((V, E), key=lambda v: -v) [7, 5, 11, 3, 10, 8, 9, 2]
只有无圈图可以排序。如果输入图有一个循环,则
ValueError
将被提升:>>> topological_sort((V, E + [(10, 7)])) Traceback (most recent call last): ... ValueError: cycle detected
工具书类
- sympy.utilities.iterables.uniq(seq, result=None)[源代码]#
从中产生独特的元素
seq
作为迭代器。第二个参数result
在内部使用;不需要为此传递任何内容。注意:如果序列的大小已知,在迭代期间更改序列将引发运行时错误;如果传递迭代器并推进迭代器,则会更改此例程的输出,但不会出现警告。
实例
>>> from sympy.utilities.iterables import uniq >>> dat = [1, 4, 1, 5, 4, 2, 1, 2] >>> type(uniq(dat)) in (list, tuple) False
>>> list(uniq(dat)) [1, 4, 5, 2] >>> list(uniq(x for x in dat)) [1, 4, 5, 2] >>> list(uniq([[1], [2, 1], [1]])) [[1], [2, 1]]
- sympy.utilities.iterables.variations(seq, n, repetition=False)[源代码]#
Returns an iterator over the n-sized variations of
seq
(size N).repetition
controls whether items inseq
can appear more than once;实例
variations(seq, n)
将返回 \(\frac{{N!}}{{(N - n)!}}\) 不重复的排列seq
的元素:>>> from sympy import variations >>> list(variations([1, 2], 2)) [(1, 2), (2, 1)]
variations(seq, n, True)
将返回 \(N^n\) 通过允许元素重复获得的排列:>>> list(variations([1, 2], 2, repetition=True)) [(1, 1), (1, 2), (2, 1), (2, 2)]
如果您要求的项目多于集合中的项目,则除非您允许重复,否则将得到空集合:
>>> list(variations([0, 1], 3, repetition=False)) [] >>> list(variations([0, 1], 3, repetition=True))[:4] [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1)]
变化#
Variance(seq,n)返回大小n列表的所有变化。
有一个可选的第三个参数。必须是布尔值,如果设置为True,则使方法返回具有重复的变体,如果设置为False,则返回不重复的变体。
- 实例:
>>> from sympy.utilities.iterables import variations >>> list(variations([1,2,3], 2)) [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)] >>> list(variations([1,2,3], 2, True)) [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]
隔墙#
Although the combinatorics module contains Partition and IntegerPartition
classes for investigation and manipulation of partitions, there are a few
functions to generate partitions that can be used as low-level tools for
routines: partitions
and multiset_partitions
. The former gives
integer partitions, and the latter gives enumerated partitions of elements.
There is also a routine kbins
that will give a variety of permutations
of partitions. And to obtain partitions as a list instead of a dictionary, there
is the ordered_partition
function which is quite fast. Finally, to simply
obtain a count of the number of partitions without enumerating them, there
is the nT
function.
也见#
sympy.utilities.iterables.ordered_partitions, sympy.functions.combinatorial.numbers.nT
分区::
>>> from sympy.utilities.iterables import partitions
>>> [p.copy() for s, p in partitions(7, m=2, size=True) if s == 2]
[{1: 1, 6: 1}, {2: 1, 5: 1}, {3: 1, 4: 1}]
多集分区:
>>> from sympy.utilities.iterables import multiset_partitions
>>> [p for p in multiset_partitions(3, 2)]
[[[0, 1], [2]], [[0, 2], [1]], [[0], [1, 2]]]
>>> [p for p in multiset_partitions([1, 1, 1, 2], 2)]
[[[1, 1, 1], [2]], [[1, 1, 2], [1]], [[1, 1], [1, 2]]]
kbins::
>>> from sympy.utilities.iterables import kbins
>>> def show(k):
... rv = []
... for p in k:
... rv.append(','.join([''.join(j) for j in p]))
... return sorted(rv)
...
>>> show(kbins("ABCD", 2))
['A,BCD', 'AB,CD', 'ABC,D']
>>> show(kbins("ABC", 2))
['A,BC', 'AB,C']
>>> show(kbins("ABC", 2, ordered=0)) # same as multiset_partitions
['A,BC', 'AB,C', 'AC,B']
>>> show(kbins("ABC", 2, ordered=1))
['A,BC', 'A,CB',
'B,AC', 'B,CA',
'C,AB', 'C,BA']
>>> show(kbins("ABC", 2, ordered=10))
['A,BC', 'AB,C', 'AC,B',
'B,AC', 'BC,A',
'C,AB']
>>> show(kbins("ABC", 2, ordered=11))
['A,BC', 'A,CB', 'AB,C', 'AC,B',
'B,AC', 'B,CA', 'BA,C', 'BC,A',
'C,AB', 'C,BA', 'CA,B', 'CB,A']