有限函数的有限集、图像和前图像的惯用Python实现?

有限函数的有限集、图像和前图像的惯用Python实现?,python,discrete-mathematics,Python,Discrete Mathematics,假设在有限集之间有一个有限的具体函数。当然,Python已经在本地实现了集合 但是,准确地说,实现集合间有限函数概念的最佳方法是什么?包装好的字典?另外,如何实现图像和前图像的计算?[见下文。] 对于图像,我可以使用地图,很明显。对于预映像,我可以在域集合和过滤器上循环。尽管如此,我还是想知道更具Python风格的惯用解决方案 对于从一个集合到另一个集合的任意图像,我将使用Python字典。例如,在{1,2,3,4}的集合上,f(n)=n^2,我可以这样做: preimage = set([1,

假设在有限集之间有一个有限的具体函数。当然,Python已经在本地实现了集合

但是,准确地说,实现集合间有限函数概念的最佳方法是什么?包装好的字典?另外,如何实现图像和前图像的计算?[见下文。]

对于图像,我可以使用地图,很明显。对于预映像,我可以在域集合和过滤器上循环。尽管如此,我还是想知道更具Python风格的惯用解决方案


对于从一个集合到另一个集合的任意图像,我将使用Python字典。例如,在{1,2,3,4}的集合上,f(n)=n^2,我可以这样做:

preimage = set([1,2,3,4])
mapping = {x: x*x for x in preimage}
image = set(mapping.values())
assert set(mapping.keys()) == preimage
function = lambda x: mapping[x] # so you can now have y = function(x)
check_image = set([function(x) for x in preimage])
assert check_image == image
当然,这只适用于有限集对于内存来说确实是有限的情况

以上是将函数定义为映射的最常见的情况。但对于可以用Python表达式表示的更简单的函数,可以跳过字典:

preimage = set([1,2,3,4])
function = lambda x: x*x
image = set([function(x) for x in preimage])
check_preimage = set([y for x in image for y in preimage if function(y)==x])
assert check_preimage == preimage
如果进一步,你有一个反函数可用于域:

import math
preimage = set([1,2,3,4])
function = lambda x: x*x
inv_func = lambda x: int(math.sqrt(x))
image = set([function(x) for x in preimage])
check_preimage = set([inv_func(x) for x in image])
assert check_preimage == preimage
请注意,以上三个不同的代码片段中,只有第一个可以保证
函数(x)
只允许预定义的前映像中的
x


说到惯用的python:我不认为python真的是一种数学语言(与Wolfram的mathematica相比),因此我们没有内置图像、映射等概念。但是,您可以在上面的列表中看到我的代码。事实上,我只是更明确地使用了
set
关键字,如
set([function(x)for x in preimage])
,但是您可以使用
{function(x)for x in preimage}
来保存一些按键,对于从一个集合到另一个集合的任意图像,我会使用Python字典。例如,在{1,2,3,4}的集合上,f(n)=n^2,我可以这样做:

preimage = set([1,2,3,4])
mapping = {x: x*x for x in preimage}
image = set(mapping.values())
assert set(mapping.keys()) == preimage
function = lambda x: mapping[x] # so you can now have y = function(x)
check_image = set([function(x) for x in preimage])
assert check_image == image
def preimage(b: B, f: Dict[A, B]) -> Set[A]: 
    ''' get the preimage of one item. '''
    return set(a for a in f.keys() if f[a]==b)
当然,这只适用于有限集对于内存来说确实是有限的情况

以上是将函数定义为映射的最常见的情况。但对于可以用Python表达式表示的更简单的函数,可以跳过字典:

preimage = set([1,2,3,4])
function = lambda x: x*x
image = set([function(x) for x in preimage])
check_preimage = set([y for x in image for y in preimage if function(y)==x])
assert check_preimage == preimage
如果进一步,你有一个反函数可用于域:

import math
preimage = set([1,2,3,4])
function = lambda x: x*x
inv_func = lambda x: int(math.sqrt(x))
image = set([function(x) for x in preimage])
check_preimage = set([inv_func(x) for x in image])
assert check_preimage == preimage
请注意,以上三个不同的代码片段中,只有第一个可以保证
函数(x)
只允许预定义的前映像中的
x

说到惯用的python:我不认为python真的是一种数学语言(与Wolfram的mathematica相比),因此我们没有内置图像、映射等概念。但是,您可以在上面的列表中看到我的代码。事实上,我只是更明确地使用了
set
关键字,如
set([function(x)for x in preimage])
,但是您可以使用
{function(x)for x in preimage}
保存一些击键

def preimage(b: B, f: Dict[A, B]) -> Set[A]: 
    ''' get the preimage of one item. '''
    return set(a for a in f.keys() if f[a]==b)
这假设

如果没有类型注释,则如下所示

def preimage(b, f): 
  ...
或者是编码域的一个子集

from typing import Collection
from functools import reduce

def preimage_(bs: Collection[B], f: Dict[A, B]) -> Set[A]: 
    ''' get the preimage of a collection of items '''
    return reduce(lambda a, b: a.union(b), [preimage(b, f) for b in bs])
这假设

如果没有类型注释,则如下所示

def preimage(b, f): 
  ...
或者是编码域的一个子集

from typing import Collection
from functools import reduce

def preimage_(bs: Collection[B], f: Dict[A, B]) -> Set[A]: 
    ''' get the preimage of a collection of items '''
    return reduce(lambda a, b: a.union(b), [preimage(b, f) for b in bs])

我可以对前照做同样的事情,是的。现在,这只是一个将有限函数表示为对象的最佳方式的问题。扩展答案来回答你的问题。我可以对前图像做同样的事情,是的。现在,这只是一个将有限函数表示为对象的最佳方式的问题。展开答案以回答您的问题。