为 Python L 系统重写系统
Rewriting System for Python L-System
我为 Python 生成了以下工作代码。这是一个基于 Lindenmayer 的重写系统。输出 C 是:+-LF+RFR+FL-F-+RF-LFL-FR+F+RF-LFL-FR+-F-LF+RFR+FL-+
,我可以将其解释为绘制 space 填充曲线。 C为起始字母,执行n次。
C = 'L'
n = 2
Code = {ord('L'):'+RF-LFL-FR+',
ord('R'):'-LF+RFR+FL-'}
while n:
C = C.translate(Code)
n -=1
print C
现在我想要的是,代码是从列表中自动编写的。例如,我有列表 R=[['L', '+RF-LFL-FR+'], ['R', '-LF+RFR+FL-']]
应该自动插入到代码中,所以我可以进一步使用它。每个子列表的第一个元素应该插入 ord()
方法中,第二个元素在冒号之后。有什么建议吗?
我通过列表理解找到了一种方法。列表 R 是 L=+RF-LFL-FR+, R=-LF+RFR+FL-
。现在请问有没有更高效的获取代码的方法?
R = ['L=+RF-LFL-FR+','R=-LF+RFR+FL-']
A = 'L'
for i in range(0,len(R)):
R[i]=R[i].split('=')
print R
Start = []
Rule = []
for i in range(0,len(R)):
Start.append(R[i][0])
Rule.append(R[i][1])
#mapping via list comprehension
while n:
A=''.join([Rule[Start.index(i)] if i in Start else i for i in A])
n -=1
print A
显然这似乎对你有用。代码在 python3.
上运行
def fun1(n):
axiom = 'L'
rules = ['L=+RF-LFL-FR+','R=-LF+RFR+FL-']
# Convert the rules into a translation table.
rules = [ r.split('=') for r in rules ]
table = dict((ord(key), value) for (key, value) in dict(rules).items())
# Expand
string = axiom
for i in range(n):
string = string.translate(table)
return string
编辑:
我找到了第二种使用内置 map
函数的方法:
def fun2(n):
axiom = 'L'
rules = ['L=+RF-LFL-FR+','R=-LF+RFR+FL-']
# Convert the rules into a translation table.
rules = [ r.split('=') for r in rules ]
table = dict(rules)
lookup = lambda c: table[c] if c in table else c
string = axiom
for i in range(n):
# Map
string = map(lookup, string)
# "Reduce": from list of strings to string
string = ''.join(string)
return string
时机:
为了检查运行时间,我执行了 n=10
的候选项,这导致生成的字符串包含大约 3'500'000 个字符。你的实现(当然没有打印操作)我命名为 fun3(n)
。我在ipython
.
中使用%timeit
命令测得的结果
%timeit fun1(n=10)
10 loops, best of 3: 143 ms per loop
%timeit fun2(n=10)
10 loops, best of 3: 195 ms per loop
%timeit fun3(n=10)
10 loops, best of 3: 152 ms per loop
系统:Python 3.5.2.,MacBook Pro(Retina,15 英寸,2015 年中),2.8 GHz Intel Core i7。
总结:我的第一个建议和你的实现执行起来差不多一样快,我的版本略有优势,特别是在可读性方面。 map
方法没有回报。
我还尝试了第四个版本,其中输出数组是预分配的,但是代码变得复杂并且 python 的内存分配逻辑在运行时明显优于我的预分配方法 2 倍。我没有对此进行进一步调查。
我为 Python 生成了以下工作代码。这是一个基于 Lindenmayer 的重写系统。输出 C 是:+-LF+RFR+FL-F-+RF-LFL-FR+F+RF-LFL-FR+-F-LF+RFR+FL-+
,我可以将其解释为绘制 space 填充曲线。 C为起始字母,执行n次。
C = 'L'
n = 2
Code = {ord('L'):'+RF-LFL-FR+',
ord('R'):'-LF+RFR+FL-'}
while n:
C = C.translate(Code)
n -=1
print C
现在我想要的是,代码是从列表中自动编写的。例如,我有列表 R=[['L', '+RF-LFL-FR+'], ['R', '-LF+RFR+FL-']]
应该自动插入到代码中,所以我可以进一步使用它。每个子列表的第一个元素应该插入 ord()
方法中,第二个元素在冒号之后。有什么建议吗?
我通过列表理解找到了一种方法。列表 R 是 L=+RF-LFL-FR+, R=-LF+RFR+FL-
。现在请问有没有更高效的获取代码的方法?
R = ['L=+RF-LFL-FR+','R=-LF+RFR+FL-']
A = 'L'
for i in range(0,len(R)):
R[i]=R[i].split('=')
print R
Start = []
Rule = []
for i in range(0,len(R)):
Start.append(R[i][0])
Rule.append(R[i][1])
#mapping via list comprehension
while n:
A=''.join([Rule[Start.index(i)] if i in Start else i for i in A])
n -=1
print A
显然这似乎对你有用。代码在 python3.
上运行def fun1(n):
axiom = 'L'
rules = ['L=+RF-LFL-FR+','R=-LF+RFR+FL-']
# Convert the rules into a translation table.
rules = [ r.split('=') for r in rules ]
table = dict((ord(key), value) for (key, value) in dict(rules).items())
# Expand
string = axiom
for i in range(n):
string = string.translate(table)
return string
编辑:
我找到了第二种使用内置 map
函数的方法:
def fun2(n):
axiom = 'L'
rules = ['L=+RF-LFL-FR+','R=-LF+RFR+FL-']
# Convert the rules into a translation table.
rules = [ r.split('=') for r in rules ]
table = dict(rules)
lookup = lambda c: table[c] if c in table else c
string = axiom
for i in range(n):
# Map
string = map(lookup, string)
# "Reduce": from list of strings to string
string = ''.join(string)
return string
时机:
为了检查运行时间,我执行了 n=10
的候选项,这导致生成的字符串包含大约 3'500'000 个字符。你的实现(当然没有打印操作)我命名为 fun3(n)
。我在ipython
.
%timeit
命令测得的结果
%timeit fun1(n=10)
10 loops, best of 3: 143 ms per loop
%timeit fun2(n=10)
10 loops, best of 3: 195 ms per loop
%timeit fun3(n=10)
10 loops, best of 3: 152 ms per loop
系统:Python 3.5.2.,MacBook Pro(Retina,15 英寸,2015 年中),2.8 GHz Intel Core i7。
总结:我的第一个建议和你的实现执行起来差不多一样快,我的版本略有优势,特别是在可读性方面。 map
方法没有回报。
我还尝试了第四个版本,其中输出数组是预分配的,但是代码变得复杂并且 python 的内存分配逻辑在运行时明显优于我的预分配方法 2 倍。我没有对此进行进一步调查。